summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormorganamilo <morganamilo@archlinux.org>2019-11-27 18:45:20 +0100
committerAllan McRae <allan@archlinux.org>2019-12-02 04:56:11 +0100
commitb7f61aa55755d95d2e3a6dd7058971c68276c369 (patch)
treef8eacd0a2355d6854c2e00e6cc92ce172484f02c
parent0428f6213bcb5586d4ec9feb18af9a883c463793 (diff)
downloadpacman-b7f61aa55755d95d2e3a6dd7058971c68276c369.tar.gz
pacman-b7f61aa55755d95d2e3a6dd7058971c68276c369.tar.xz
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>
-rw-r--r--src/pacman/files.c57
1 files changed, 44 insertions, 13 deletions
diff --git a/src/pacman/files.c b/src/pacman/files.c
index 3b6dc23b..7b0c884b 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);
+ /* 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) {
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(&reg, 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(&reg, 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(&reg, (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(&reg);
- }
-
-notfound:
if(!found) {
ret = 1;
}
}
+cleanup:
+ alpm_list_free_inner(filetargs, (alpm_list_fn_free) filetarget_free);
+ alpm_list_free(filetargs);
+
return ret;
}