]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Return correct error when multiple modules match an option spec
authorTim Kientzle <kientzle@acm.org>
Sun, 23 Feb 2014 17:34:43 +0000 (09:34 -0800)
committerTim Kientzle <kientzle@acm.org>
Sun, 23 Feb 2014 17:34:43 +0000 (09:34 -0800)
libarchive/archive_read_set_options.c

index d03961e979664bcd3581b6d19f3ba04e2392373a..46678b163600b4f43b702f4ab57fb3aa9a6ac3a7 100644 (file)
@@ -78,7 +78,7 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
        struct archive_read *a = (struct archive_read *)_a;
        struct archive_format_descriptor *format;
        size_t i;
-       int r, rv = ARCHIVE_WARN;
+       int r, rv = ARCHIVE_WARN, matched_modules = 0;
 
        for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
                format = &a->formats[i];
@@ -86,8 +86,11 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
                    format->name == NULL)
                        /* This format does not support option. */
                        continue;
-               if (m != NULL && strcmp(format->name, m) != 0)
-                       continue;
+               if (m != NULL) {
+                       if (strcmp(format->name, m) != 0)
+                               continue;
+                       ++matched_modules;
+               }
 
                a->format = format;
                r = format->options(a, o, v);
@@ -101,8 +104,8 @@ archive_set_format_option(struct archive *_a, const char *m, const char *o,
        }
        /* If the format name didn't match, return a special code for
         * _archive_set_option[s]. */
-       if (rv == ARCHIVE_WARN && m != NULL)
-               rv = ARCHIVE_WARN - 1;
+       if (m != NULL && matched_modules == 0)
+               return ARCHIVE_WARN - 1;
        return (rv);
 }
 
@@ -113,7 +116,7 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
        struct archive_read *a = (struct archive_read *)_a;
        struct archive_read_filter *filter;
        struct archive_read_filter_bidder *bidder;
-       int r, rv = ARCHIVE_WARN;
+       int r, rv = ARCHIVE_WARN, matched_modules = 0;
 
        for (filter = a->filter; filter != NULL; filter = filter->upstream) {
                bidder = filter->bidder;
@@ -122,8 +125,11 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
                if (bidder->options == NULL)
                        /* This bidder does not support option */
                        continue;
-               if (m != NULL && strcmp(filter->name, m) != 0)
-                       continue;
+               if (m != NULL) {
+                       if (strcmp(filter->name, m) != 0)
+                               continue;
+                       ++matched_modules;
+               }
 
                r = bidder->options(bidder, o, v);
 
@@ -135,8 +141,8 @@ archive_set_filter_option(struct archive *_a, const char *m, const char *o,
        }
        /* If the filter name didn't match, return a special code for
         * _archive_set_option[s]. */
-       if (rv == ARCHIVE_WARN && m != NULL)
-               rv = ARCHIVE_WARN - 1;
+       if (m != NULL && matched_modules == 0)
+               return ARCHIVE_WARN - 1;
        return (rv);
 }