[pacman-dev] [PATCH v2] pacman: print error when -Fx is given invalid regex
When processing the targets for -Fx, compile all the regex ahead of time, printing an error for each that failed to compile. Then, if they all compiled successfully, continue with printing files. Signed-off-by: morganamilo <morganamilo@archlinux.org> --- v2: Add comment about why we don't free targ Fix whitespace error I have vim set to display trialing whitespace so normally I catch it. Not sure why I didn't this time. Also I agree that running all the regex against each target before moving on to the next is a good improvement. This patch is already kinda long though, so I'll do it another time. diff --git a/src/pacman/files.c b/src/pacman/files.c index 3b6dc23b..6fcc6e9b 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -94,17 +94,27 @@ static void print_match(alpm_list_t *match, alpm_db_t *repo, alpm_pkg_t *pkg, in } } +struct filetarget { + char *targ; + int exact_file; + regex_t reg; +}; + +static void filetarget_free(struct filetarget *ftarg) { + regfree(&ftarg->reg); + /* we don't own ftarg->targ so don't free it */ + free(ftarg); +} + static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { int ret = 0; - alpm_list_t *t; + alpm_list_t *t, *filetargs = NULL; for(t = targets; t; t = alpm_list_next(t)) { char *targ = t->data; - alpm_list_t *s; - int found = 0; - regex_t reg; size_t len = strlen(targ); int exact_file = strchr(targ, '/') != NULL; + regex_t reg; if(exact_file) { while(len > 1 && targ[0] == '/') { @@ -115,11 +125,33 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { if(regex) { if(regcomp(®, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) { - /* TODO: error message */ - goto notfound; + pm_printf(ALPM_LOG_ERROR, + _("invalid regular expression '%s'\n"), targ); + ret = 1; + continue; } } + struct filetarget *ftarg = malloc(sizeof(struct filetarget)); + ftarg->targ = targ; + ftarg->exact_file = exact_file; + ftarg->reg = reg; + + filetargs = alpm_list_add(filetargs, ftarg); + } + + if(ret != 0) { + goto cleanup; + } + + for(t = filetargs; t; t = alpm_list_next(t)) { + struct filetarget *ftarg = t->data; + char *targ = ftarg->targ; + regex_t *reg = &ftarg->reg; + int exact_file = ftarg->exact_file; + alpm_list_t *s; + int found = 0; + for(s = syncs; s; s = alpm_list_next(s)) { alpm_list_t *p; alpm_db_t *repo = s->data; @@ -135,7 +167,7 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { if (regex) { for(size_t f = 0; f < files->count; f++) { char *c = files->files[f].name; - if(regexec(®, c, 0, 0, 0) == 0) { + if(regexec(reg, c, 0, 0, 0) == 0) { match = alpm_list_add(match, files->files[f].name); found = 1; } @@ -151,7 +183,7 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { char *c = strrchr(files->files[f].name, '/'); if(c && *(c + 1)) { if(regex) { - m = regexec(®, (c + 1), 0, 0, 0); + m = regexec(reg, (c + 1), 0, 0, 0); } else { m = strcmp(c + 1, targ); } @@ -170,16 +202,15 @@ static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { } } - if(regex) { - regfree(®); - } - -notfound: if(!found) { ret = 1; } } +cleanup: + alpm_list_free_inner(filetargs, (alpm_list_fn_free) filetarget_free); + alpm_list_free(filetargs); + return ret; } -- 2.24.0
On 28/11/19 3:45 am, morganamilo wrote:
When processing the targets for -Fx, compile all the regex ahead of time, printing an error for each that failed to compile. Then, if they all compiled successfully, continue with printing files.
Signed-off-by: morganamilo <morganamilo@archlinux.org>
---
v2: Add comment about why we don't free targ Fix whitespace error
I have vim set to display trialing whitespace so normally I catch it. Not sure why I didn't this time.
Also I agree that running all the regex against each target before moving on to the next is a good improvement. This patch is already kinda long though, so I'll do it another time.
diff --git a/src/pacman/files.c b/src/pacman/files.c index 3b6dc23b..6fcc6e9b 100644 --- a/src/pacman/files.c +++ b/src/pacman/files.c @@ -94,17 +94,27 @@ static void print_match(alpm_list_t *match, alpm_db_t *repo, alpm_pkg_t *pkg, in } }
+struct filetarget { + char *targ; + int exact_file; + regex_t reg; +}; + +static void filetarget_free(struct filetarget *ftarg) { + regfree(&ftarg->reg); + /* we don't own ftarg->targ so don't free it */
Patch looks good. I changed that comment to: do not free ftarg->targ as it is owned by the caller of files_search This does a few useful things: 1) gets the "do not free" right at the start of the comment 2) specifies where the memory is owned 3) does not use contractions - apparently the use of "not" make the negative clearer for non-native speakers, although I am not sure what sort of evidence is behind that is claim... Allan
participants (2)
-
Allan McRae
-
morganamilo