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>
Signed-off-by: Allan McRae <allan@archlinux.org>
This commit is contained in:
morganamilo 2019-11-27 17:45:20 +00:00 committed by Allan McRae
parent 0428f6213b
commit b7f61aa557

View file

@ -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);
/* do not free ftarg->targ as it is owned by the caller of files_search */
free(ftarg);
}
static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) { static int files_search(alpm_list_t *syncs, alpm_list_t *targets, int regex) {
int ret = 0; int ret = 0;
alpm_list_t *t; alpm_list_t *t, *filetargs = NULL;
for(t = targets; t; t = alpm_list_next(t)) { for(t = targets; t; t = alpm_list_next(t)) {
char *targ = t->data; char *targ = t->data;
alpm_list_t *s;
int found = 0;
regex_t reg;
size_t len = strlen(targ); size_t len = strlen(targ);
int exact_file = strchr(targ, '/') != NULL; int exact_file = strchr(targ, '/') != NULL;
regex_t reg;
if(exact_file) { if(exact_file) {
while(len > 1 && targ[0] == '/') { 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(regex) {
if(regcomp(&reg, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) { if(regcomp(&reg, targ, REG_EXTENDED | REG_NOSUB | REG_ICASE | REG_NEWLINE) != 0) {
/* TODO: error message */ pm_printf(ALPM_LOG_ERROR,
goto notfound; _("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)) { for(s = syncs; s; s = alpm_list_next(s)) {
alpm_list_t *p; alpm_list_t *p;
alpm_db_t *repo = s->data; 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) { if (regex) {
for(size_t f = 0; f < files->count; f++) { for(size_t f = 0; f < files->count; f++) {
char *c = files->files[f].name; char *c = files->files[f].name;
if(regexec(&reg, c, 0, 0, 0) == 0) { if(regexec(reg, c, 0, 0, 0) == 0) {
match = alpm_list_add(match, files->files[f].name); match = alpm_list_add(match, files->files[f].name);
found = 1; 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, '/'); char *c = strrchr(files->files[f].name, '/');
if(c && *(c + 1)) { if(c && *(c + 1)) {
if(regex) { if(regex) {
m = regexec(&reg, (c + 1), 0, 0, 0); m = regexec(reg, (c + 1), 0, 0, 0);
} else { } else {
m = strcmp(c + 1, targ); 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(&reg);
}
notfound:
if(!found) { if(!found) {
ret = 1; ret = 1;
} }
} }
cleanup:
alpm_list_free_inner(filetargs, (alpm_list_fn_free) filetarget_free);
alpm_list_free(filetargs);
return ret; return ret;
} }