From ea4dcf9ff427e6d7fbb11194ba5db352b7e78af2 Mon Sep 17 00:00:00 2001 From: Michael Sweet Date: Thu, 7 Sep 2017 10:36:09 -0400 Subject: [PATCH] The `ipptool` program did not compare URI scheme or hostname components correctly for the WITH-ALL-HOSTNAMES, WITH-ALL-SCHEMES, WITH-HOSTNAME, or WITH-SCHEME predicates. Also fix EXPECT reporting for the URI component WITH predicates. --- CHANGES.md | 3 ++ test/ipptool.c | 117 ++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 104 insertions(+), 16 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index fc6bd4fbd3..f5f09c7b35 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -55,6 +55,9 @@ CHANGES IN CUPS V2.2.5 - Fixed the localization fallback code on macOS (rdar://33583699) - The `ipptool` program now offers an option to validate response headers. - The `ipptool` program's `-P` option did not work correctly. +- The `ipptool` program did not compare URI scheme or hostname components + correctly for the WITH-ALL-HOSTNAMES, WITH-ALL-SCHEMES, WITH-HOSTNAME, or + WITH-SCHEME predicates. CHANGES IN CUPS V2.2.4 diff --git a/test/ipptool.c b/test/ipptool.c index 2df9900943..737fde124e 100644 --- a/test/ipptool.c +++ b/test/ipptool.c @@ -180,6 +180,7 @@ static void sigterm_handler(int sig); static int timeout_cb(http_t *http, void *user_data); static void usage(void) __attribute__((noreturn)); static int validate_attr(cups_file_t *outfile, cups_array_t *errors, ipp_attribute_t *attr); +static const char *with_flags_string(int flags); static int with_value(cups_file_t *outfile, cups_array_t *errors, char *value, int flags, ipp_attribute_t *attr, char *matchbuf, size_t matchlen); static int with_value_from(cups_array_t *errors, ipp_attribute_t *fromattr, ipp_attribute_t *attr, char *matchbuf, size_t matchlen); @@ -3189,20 +3190,11 @@ do_tests(cups_file_t *outfile, /* I - Output file */ !expect->repeat_match && (!expect->repeat_no_match || repeat_count >= expect->repeat_limit)) { if (expect->with_flags & _CUPS_WITH_REGEX) - add_stringf(errors, "EXPECTED: %s %s /%s/", - expect->name, - (expect->with_flags & _CUPS_WITH_ALL) ? - "WITH-ALL-VALUES" : "WITH-VALUE", - expect->with_value); + add_stringf(errors, "EXPECTED: %s %s /%s/", expect->name, with_flags_string(expect->with_flags), expect->with_value); else - add_stringf(errors, "EXPECTED: %s %s \"%s\"", - expect->name, - (expect->with_flags & _CUPS_WITH_ALL) ? - "WITH-ALL-VALUES" : "WITH-VALUE", - expect->with_value); - - with_value(outfile, errors, expect->with_value, expect->with_flags, found, - buffer, sizeof(buffer)); + add_stringf(errors, "EXPECTED: %s %s \"%s\"", expect->name, with_flags_string(expect->with_flags), expect->with_value); + + with_value(outfile, errors, expect->with_value, expect->with_flags, found, buffer, sizeof(buffer)); } if (expect->repeat_no_match && @@ -5759,6 +5751,36 @@ validate_attr(cups_file_t *outfile, /* I - Output file */ } +/* + * 'with_flags_string()' - Return the "WITH-xxx" predicate that corresponds to + the flags. + */ + +static const char * /* O - WITH-xxx string */ +with_flags_string(int flags) /* I - WITH flags */ +{ + if (flags & _CUPS_WITH_ALL) + { + if (flags & _CUPS_WITH_HOSTNAME) + return ("WITH-ALL-HOSTNAMES"); + else if (flags & _CUPS_WITH_RESOURCE) + return ("WITH-ALL-RESOURCES"); + else if (flags & _CUPS_WITH_SCHEME) + return ("WITH-ALL-SCHEMES"); + else + return ("WITH-ALL-VALUES"); + } + else if (flags & _CUPS_WITH_HOSTNAME) + return ("WITH-HOSTNAME"); + else if (flags & _CUPS_WITH_RESOURCE) + return ("WITH-RESOURCE"); + else if (flags & _CUPS_WITH_SCHEME) + return ("WITH-SCHEME"); + else + return ("WITH-VALUE"); +} + + /* * 'with_value()' - Test a WITH-VALUE predicate. */ @@ -6075,7 +6097,7 @@ with_value(cups_file_t *outfile, /* I - Output file */ regfree(&re); } - else if (ippGetValueTag(attr) == IPP_TAG_URI) + else if (ippGetValueTag(attr) == IPP_TAG_URI && !(flags & (_CUPS_WITH_SCHEME | _CUPS_WITH_HOSTNAME | _CUPS_WITH_RESOURCE))) { /* * Value is a literal URI string, see if the value(s) match... @@ -6111,7 +6133,46 @@ with_value(cups_file_t *outfile, /* I - Output file */ for (i = 0; i < attr->num_values; i ++) { - if (!strcmp(value, get_string(attr, i, flags, temp, sizeof(temp)))) + int result; + + switch (ippGetValueTag(attr)) + { + case IPP_TAG_URI : + /* + * Some URI components are case-sensitive, some not... + */ + + if (flags & (_CUPS_WITH_SCHEME | _CUPS_WITH_HOSTNAME)) + result = _cups_strcasecmp(value, get_string(attr, i, flags, temp, sizeof(temp))); + else + result = strcmp(value, get_string(attr, i, flags, temp, sizeof(temp))); + break; + + case IPP_TAG_MIMETYPE : + case IPP_TAG_NAME : + case IPP_TAG_NAMELANG : + case IPP_TAG_TEXT : + case IPP_TAG_TEXTLANG : + /* + * mimeMediaType, nameWithoutLanguage, nameWithLanguage, + * textWithoutLanguage, and textWithLanguage are defined to + * be case-insensitive strings... + */ + + result = _cups_strcasecmp(value, get_string(attr, i, flags, temp, sizeof(temp))); + break; + + default : + /* + * Other string syntaxes are defined as lowercased so we use + * case-sensitive comparisons to catch problems... + */ + + result = strcmp(value, get_string(attr, i, flags, temp, sizeof(temp))); + break; + } + + if (!result) { if (!matchbuf[0]) strlcpy(matchbuf, @@ -6272,7 +6333,6 @@ with_value_from( case IPP_TAG_NAMELANG : case IPP_TAG_TEXT : case IPP_TAG_TEXTLANG : - case IPP_TAG_URI : case IPP_TAG_URISCHEME : for (i = 0; i < count; i ++) { @@ -6292,6 +6352,31 @@ with_value_from( } break; + case IPP_TAG_URI : + for (i = 0; i < count; i ++) + { + const char *value = ippGetString(attr, i, NULL); + /* Current string value */ + int fromcount = ippGetCount(fromattr); + + for (j = 0; j < fromcount; j ++) + { + if (!compare_uris(value, ippGetString(fromattr, j, NULL))) + { + if (!matchbuf[0]) + strlcpy(matchbuf, value, matchlen); + break; + } + } + + if (j >= fromcount) + { + add_stringf(errors, "GOT: %s='%s'", ippGetName(attr), value); + match = 0; + } + } + break; + default : match = 0; break; -- 2.47.3