X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=cups%2Fipp.c;h=0248cb9d295a01d365e5c49eec29b31b19bd4200;hb=aa15a57207d90c1b78c2e6ee31056cfa4cc641f2;hp=1964962ce4c6c91e90bb5ee68cd5cebd03d398ee;hpb=6ee5217845b2392402a50906b25eb242de753f6a;p=thirdparty%2Fcups.git diff --git a/cups/ipp.c b/cups/ipp.c index 1964962ce..0248cb9d2 100644 --- a/cups/ipp.c +++ b/cups/ipp.c @@ -1,16 +1,11 @@ /* * Internet Printing Protocol functions for CUPS. * - * Copyright 2007-2015 by Apple Inc. - * Copyright 1997-2007 by Easy Software Products, all rights reserved. + * Copyright © 2007-2019 by Apple Inc. + * Copyright © 1997-2007 by Easy Software Products, all rights reserved. * - * These coded instructions, statements, and computer programs are the - * property of Apple Inc. and are protected by Federal copyright - * law. Distribution and use rights are outlined in the file "LICENSE.txt" - * which should have been included with this file. If this file is - * file is missing or damaged, see the license at "http://www.cups.org/". - * - * This file is subject to the Apple OS-Developed Software exception. + * Licensed under Apache License v2.0. See the file "LICENSE" for more + * information. */ /* @@ -18,10 +13,11 @@ */ #include "cups-private.h" +#include "debug-internal.h" #include -#ifdef WIN32 +#ifdef _WIN32 # include -#endif /* WIN32 */ +#endif /* _WIN32 */ /* @@ -33,12 +29,8 @@ static ipp_attribute_t *ipp_add_attr(ipp_t *ipp, const char *name, int num_values); static void ipp_free_values(ipp_attribute_t *attr, int element, int count); -static char *ipp_get_code(const char *locale, char *buffer, - size_t bufsize) - __attribute__((nonnull(1,2))); -static char *ipp_lang_code(const char *locale, char *buffer, - size_t bufsize) - __attribute__((nonnull(1,2))); +static char *ipp_get_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL(1,2); +static char *ipp_lang_code(const char *locale, char *buffer, size_t bufsize) _CUPS_NONNULL(1,2); static size_t ipp_length(ipp_t *ipp, int collection); static ssize_t ipp_read_http(http_t *http, ipp_uchar_t *buffer, size_t length); @@ -316,7 +308,7 @@ ippAddCollections( /* - * 'ippAddDate()' - Add a date attribute to an IPP message. + * 'ippAddDate()' - Add a dateTime attribute to an IPP message. * * The @code ipp@ parameter refers to an IPP message previously created using * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions. @@ -1380,7 +1372,7 @@ ippContainsInteger( * specified string value. * * Returns non-zero when the attribute contains a matching charset, keyword, - * language, mimeMediaType, name, text, URI, or URI scheme value. + * naturalLanguage, mimeMediaType, name, text, uri, or uriScheme value. * * @since CUPS 1.7/macOS 10.9@ */ @@ -1419,13 +1411,27 @@ ippContainsString( case IPP_TAG_CHARSET : case IPP_TAG_KEYWORD : case IPP_TAG_LANGUAGE : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + for (i = attr->num_values, avalue = attr->values; + i > 0; + i --, avalue ++) + { + DEBUG_printf(("1ippContainsString: value[%d]=\"%s\"", + attr->num_values - i, avalue->string.text)); + + if (!strcmp(value, avalue->string.text)) + { + DEBUG_puts("1ippContainsString: Returning 1 (match)"); + return (1); + } + } + case IPP_TAG_MIMETYPE : case IPP_TAG_NAME : case IPP_TAG_NAMELANG : case IPP_TAG_TEXT : case IPP_TAG_TEXTLANG : - case IPP_TAG_URI : - case IPP_TAG_URISCHEME : for (i = attr->num_values, avalue = attr->values; i > 0; i --, avalue ++) @@ -1433,7 +1439,7 @@ ippContainsString( DEBUG_printf(("1ippContainsString: value[%d]=\"%s\"", attr->num_values - i, avalue->string.text)); - if (!strcmp(value, avalue->string.text)) + if (!_cups_strcasecmp(value, avalue->string.text)) { DEBUG_puts("1ippContainsString: Returning 1 (match)"); return (1); @@ -1469,6 +1475,7 @@ ippCopyAttribute( int quickcopy) /* I - 1 for a referenced copy, 0 for normal */ { int i; /* Looping var */ + ipp_tag_t srctag; /* Source value tag */ ipp_attribute_t *dstattr; /* Destination attribute */ _ipp_value_t *srcval, /* Source value */ *dstval; /* Destination value */ @@ -1487,144 +1494,86 @@ ippCopyAttribute( * Copy it... */ - quickcopy = quickcopy ? IPP_TAG_CUPS_CONST : 0; + quickcopy = (quickcopy && (srcattr->value_tag & IPP_TAG_CUPS_CONST)) ? IPP_TAG_CUPS_CONST : 0; + srctag = srcattr->value_tag & IPP_TAG_CUPS_MASK; - switch (srcattr->value_tag & ~IPP_TAG_CUPS_CONST) + switch (srctag) { case IPP_TAG_ZERO : dstattr = ippAddSeparator(dst); break; - case IPP_TAG_INTEGER : - case IPP_TAG_ENUM : - dstattr = ippAddIntegers(dst, srcattr->group_tag, srcattr->value_tag, - srcattr->name, srcattr->num_values, NULL); - if (!dstattr) - break; - - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->integer = srcval->integer; + case IPP_TAG_UNSUPPORTED_VALUE : + case IPP_TAG_DEFAULT : + case IPP_TAG_UNKNOWN : + case IPP_TAG_NOVALUE : + case IPP_TAG_NOTSETTABLE : + case IPP_TAG_DELETEATTR : + case IPP_TAG_ADMINDEFINE : + dstattr = ippAddOutOfBand(dst, srcattr->group_tag, srctag, srcattr->name); break; + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : case IPP_TAG_BOOLEAN : - dstattr = ippAddBooleans(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, NULL); - if (!dstattr) - break; - - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->boolean = srcval->boolean; + case IPP_TAG_DATE : + case IPP_TAG_RESOLUTION : + case IPP_TAG_RANGE : + if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) != NULL) + memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t)); break; case IPP_TAG_TEXT : case IPP_TAG_NAME : + case IPP_TAG_RESERVED_STRING : case IPP_TAG_KEYWORD : case IPP_TAG_URI : case IPP_TAG_URISCHEME : case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : - dstattr = ippAddStrings(dst, srcattr->group_tag, - (ipp_tag_t)(srcattr->value_tag | quickcopy), - srcattr->name, srcattr->num_values, NULL, NULL); - if (!dstattr) + if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL) break; if (quickcopy) { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->string.text = srcval->string.text; + /* + * Can safely quick-copy these string values... + */ + + memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t)); } - else if (srcattr->value_tag & IPP_TAG_CUPS_CONST) - { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->string.text = _cupsStrAlloc(srcval->string.text); - } else { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - dstval->string.text = _cupsStrRetain(srcval->string.text); - } - break; - - case IPP_TAG_DATE : - if (srcattr->num_values != 1) - return (NULL); - - dstattr = ippAddDate(dst, srcattr->group_tag, srcattr->name, - srcattr->values[0].date); - break; - - case IPP_TAG_RESOLUTION : - dstattr = ippAddResolutions(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, IPP_RES_PER_INCH, - NULL, NULL); - if (!dstattr) - break; - - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - dstval->resolution.xres = srcval->resolution.xres; - dstval->resolution.yres = srcval->resolution.yres; - dstval->resolution.units = srcval->resolution.units; - } - break; - - case IPP_TAG_RANGE : - dstattr = ippAddRanges(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, NULL, NULL); - if (!dstattr) - break; + /* + * Otherwise do a normal reference counted copy... + */ - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - dstval->range.lower = srcval->range.lower; - dstval->range.upper = srcval->range.upper; + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) + dstval->string.text = _cupsStrAlloc(srcval->string.text); } break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : - dstattr = ippAddStrings(dst, srcattr->group_tag, - (ipp_tag_t)(srcattr->value_tag | quickcopy), - srcattr->name, srcattr->num_values, NULL, NULL); - if (!dstattr) + if ((dstattr = ippAddStrings(dst, srcattr->group_tag, (ipp_tag_t)(srctag | quickcopy), srcattr->name, srcattr->num_values, NULL, NULL)) == NULL) break; if (quickcopy) { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - dstval->string.language = srcval->string.language; - dstval->string.text = srcval->string.text; - } + /* + * Can safely quick-copy these string values... + */ + + memcpy(dstattr->values, srcattr->values, (size_t)srcattr->num_values * sizeof(_ipp_value_t)); } else if (srcattr->value_tag & IPP_TAG_CUPS_CONST) { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) + /* + * Otherwise do a normal reference counted copy... + */ + + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) { if (srcval == srcattr->values) dstval->string.language = _cupsStrAlloc(srcval->string.language); @@ -1634,32 +1583,13 @@ ippCopyAttribute( dstval->string.text = _cupsStrAlloc(srcval->string.text); } } - else - { - for (i = srcattr->num_values, srcval = srcattr->values, - dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) - { - if (srcval == srcattr->values) - dstval->string.language = _cupsStrRetain(srcval->string.language); - else - dstval->string.language = dstattr->values[0].string.language; - - dstval->string.text = _cupsStrRetain(srcval->string.text); - } - } break; case IPP_TAG_BEGIN_COLLECTION : - dstattr = ippAddCollections(dst, srcattr->group_tag, srcattr->name, - srcattr->num_values, NULL); - if (!dstattr) + if ((dstattr = ippAddCollections(dst, srcattr->group_tag, srcattr->name, srcattr->num_values, NULL)) == NULL) break; - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) { dstval->collection = srcval->collection; srcval->collection->use ++; @@ -1668,15 +1598,10 @@ ippCopyAttribute( case IPP_TAG_STRING : default : - /* TODO: Implement quick copy for unknown/octetString values */ - dstattr = ippAddIntegers(dst, srcattr->group_tag, srcattr->value_tag, - srcattr->name, srcattr->num_values, NULL); - if (!dstattr) + if ((dstattr = ipp_add_attr(dst, srcattr->name, srcattr->group_tag, srctag, srcattr->num_values)) == NULL) break; - for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; - i > 0; - i --, srcval ++, dstval ++) + for (i = srcattr->num_values, srcval = srcattr->values, dstval = dstattr->values; i > 0; i --, srcval ++, dstval ++) { dstval->unknown.length = srcval->unknown.length; @@ -1745,12 +1670,12 @@ ippCopyAttributes( /* - * 'ippDateToTime()' - Convert from RFC 1903 Date/Time format to UNIX time - * in seconds. + * 'ippDateToTime()' - Convert from RFC 2579 Date/Time format to time in + * seconds. */ time_t /* O - UNIX time value */ -ippDateToTime(const ipp_uchar_t *date) /* I - RFC 1903 date info */ +ippDateToTime(const ipp_uchar_t *date) /* I - RFC 2579 date info */ { struct tm unixdate; /* UNIX date/time info */ time_t t; /* Computed time */ @@ -1762,7 +1687,7 @@ ippDateToTime(const ipp_uchar_t *date) /* I - RFC 1903 date info */ memset(&unixdate, 0, sizeof(unixdate)); /* - * RFC-1903 date/time format is: + * RFC-2579 date/time format is: * * Byte(s) Description * ------- ----------- @@ -1814,12 +1739,19 @@ ippDelete(ipp_t *ipp) /* I - IPP message */ ipp->use --; if (ipp->use > 0) + { + DEBUG_printf(("4debug_retain: %p IPP message (use=%d)", (void *)ipp, ipp->use)); return; + } + + DEBUG_printf(("4debug_free: %p IPP message", (void *)ipp)); for (attr = ipp->attrs; attr != NULL; attr = next) { next = attr->next; + DEBUG_printf(("4debug_free: %p %s %s%s (%d values)", (void *)attr, attr->name, attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), attr->num_values)); + ipp_free_values(attr, 0, attr->num_values); if (attr->name) @@ -1856,6 +1788,8 @@ ippDeleteAttribute( if (!attr) return; + DEBUG_printf(("4debug_free: %p %s %s%s (%d values)", (void *)attr, attr->name, attr->num_values > 1 ? "1setOf " : "", ippTagString(attr->value_tag), attr->num_values)); + /* * Find the attribute in the list... */ @@ -2138,7 +2072,7 @@ ippFirstAttribute(ipp_t *ipp) /* I - IPP message */ * 'ippGetBoolean()' - Get a boolean value for an attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.6/macOS 10.8@ */ @@ -2167,7 +2101,7 @@ ippGetBoolean(ipp_attribute_t *attr, /* I - IPP attribute */ * 'ippGetCollection()' - Get a collection value for an attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.6/macOS 10.8@ */ @@ -2218,15 +2152,15 @@ ippGetCount(ipp_attribute_t *attr) /* I - IPP attribute */ /* - * 'ippGetDate()' - Get a date value for an attribute. + * 'ippGetDate()' - Get a dateTime value for an attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.6/macOS 10.8@ */ -const ipp_uchar_t * /* O - Date value or @code NULL@ */ +const ipp_uchar_t * /* O - dateTime value or @code NULL@ */ ippGetDate(ipp_attribute_t *attr, /* I - IPP attribute */ int element) /* I - Value number (0-based) */ { @@ -2274,7 +2208,7 @@ ippGetGroupTag(ipp_attribute_t *attr) /* I - IPP attribute */ * 'ippGetInteger()' - Get the integer/enum value for an attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.6/macOS 10.8@ */ @@ -2327,7 +2261,7 @@ ippGetName(ipp_attribute_t *attr) /* I - IPP attribute */ * 'ippGetOctetString()' - Get an octetString value from an IPP attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.7/macOS 10.9@ */ @@ -2390,7 +2324,7 @@ ippGetOperation(ipp_t *ipp) /* I - IPP request message */ * 'ippGetRange()' - Get a rangeOfInteger value from an attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.6/macOS 10.8@ */ @@ -2452,7 +2386,7 @@ ippGetRequestId(ipp_t *ipp) /* I - IPP message */ * 'ippGetResolution()' - Get a resolution value for an attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.6/macOS 10.8@ */ @@ -2546,7 +2480,7 @@ ippGetStatusCode(ipp_t *ipp) /* I - IPP response or event message */ * 'ippGetString()' - Get the string and optionally the language code for an attribute. * * The @code element@ parameter specifies which value to get from 0 to - * @link ippGetCount(attr)@ - 1. + * @code ippGetCount(attr)@ - 1. * * @since CUPS 1.6/macOS 10.8@ */ @@ -2556,13 +2490,16 @@ ippGetString(ipp_attribute_t *attr, /* I - IPP attribute */ int element, /* I - Value number (0-based) */ const char **language)/* O - Language code (@code NULL@ for don't care) */ { + ipp_tag_t tag; /* Value tag */ + + /* * Range check input... */ - if (!attr || element < 0 || element >= attr->num_values || - (attr->value_tag != IPP_TAG_TEXTLANG && attr->value_tag != IPP_TAG_NAMELANG && - (attr->value_tag < IPP_TAG_TEXT || attr->value_tag > IPP_TAG_MIMETYPE))) + tag = ippGetValueTag(attr); + + if (!attr || element < 0 || element >= attr->num_values || (tag != IPP_TAG_TEXTLANG && tag != IPP_TAG_NAMELANG && (tag < IPP_TAG_TEXT || tag > IPP_TAG_MIMETYPE))) return (NULL); /* @@ -2608,7 +2545,7 @@ ippGetValueTag(ipp_attribute_t *attr) /* I - IPP attribute */ int /* O - Major version number or 0 on error */ ippGetVersion(ipp_t *ipp, /* I - IPP message */ - int *minor) /* O - Minor version number or @code NULL@ */ + int *minor) /* O - Minor version number or @code NULL@ for don't care */ { /* * Range check input... @@ -2688,6 +2625,8 @@ ippNew(void) * Set default version - usually 2.0... */ + DEBUG_printf(("4debug_alloc: %p IPP message", (void *)temp)); + if (cg->server_version == 0) _cupsSetDefaults(); @@ -2705,9 +2644,9 @@ ippNew(void) /* * 'ippNewRequest()' - Allocate a new IPP request message. * - * The new request message is initialized with the attributes-charset and - * attributes-natural-language attributes added. The - * attributes-natural-language value is derived from the current locale. + * The new request message is initialized with the "attributes-charset" and + * "attributes-natural-language" attributes added. The + * "attributes-natural-language" value is derived from the current locale. * * @since CUPS 1.2/macOS 10.5@ */ @@ -2769,11 +2708,11 @@ ippNewRequest(ipp_op_t op) /* I - Operation code */ /* * 'ippNewResponse()' - Allocate a new IPP response message. * - * The new response message is initialized with the same version-number, - * request-id, attributes-charset, and attributes-natural-language as the - * provided request message. If the attributes-charset or - * attributes-natural-language attributes are missing from the request, - * "utf-8" and a value derived from the current locale are substituted, + * The new response message is initialized with the same "version-number", + * "request-id", "attributes-charset", and "attributes-natural-language" as the + * provided request message. If the "attributes-charset" or + * "attributes-natural-language" attributes are missing from the request, + * 'utf-8' and a value derived from the current locale are substituted, * respectively. * * @since CUPS 1.7/macOS 10.9@ @@ -3051,6 +2990,13 @@ ippReadIO(void *src, /* I - Data source */ ipp->state = IPP_STATE_DATA; break; } + else if (tag == IPP_TAG_ZERO || (tag == IPP_TAG_OPERATION && ipp->curtag != IPP_TAG_ZERO)) + { + _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Invalid group tag."), 1); + DEBUG_printf(("1ippReadIO: bad tag 0x%02x.", tag)); + _cupsBufferRelease((char *)buffer); + return (IPP_STATE_ERROR); + } else if (tag < IPP_TAG_UNSUPPORTED_VALUE) { /* @@ -3348,7 +3294,10 @@ ippReadIO(void *src, /* I - Data source */ value->boolean = (char)buffer[0]; break; - case IPP_TAG_NOVALUE : + case IPP_TAG_UNSUPPORTED_VALUE : + case IPP_TAG_DEFAULT : + case IPP_TAG_UNKNOWN : + case IPP_TAG_NOVALUE : case IPP_TAG_NOTSETTABLE : case IPP_TAG_DELETEATTR : case IPP_TAG_ADMINDEFINE : @@ -3368,6 +3317,7 @@ ippReadIO(void *src, /* I - Data source */ case IPP_TAG_TEXT : case IPP_TAG_NAME : + case IPP_TAG_RESERVED_STRING : case IPP_TAG_KEYWORD : case IPP_TAG_URI : case IPP_TAG_URISCHEME : @@ -3622,6 +3572,7 @@ ippReadIO(void *src, /* I - Data source */ DEBUG_printf(("2ippReadIO: member name=\"%s\"", attr->name)); break; + case IPP_TAG_STRING : default : /* Other unsupported values */ if (tag == IPP_TAG_STRING && n > IPP_MAX_LENGTH) { @@ -3689,7 +3640,7 @@ ippReadIO(void *src, /* I - Data source */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.6/macOS 10.8@ */ @@ -3731,7 +3682,7 @@ ippSetBoolean(ipp_t *ipp, /* I - IPP message */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.6/macOS 10.8@ */ @@ -3772,7 +3723,7 @@ ippSetCollection( /* - * 'ippSetDate()' - Set a date value in an attribute. + * 'ippSetDate()' - Set a dateTime value in an attribute. * * The @code ipp@ parameter refers to an IPP message previously created using * the @link ippNew@, @link ippNewRequest@, or @link ippNewResponse@ functions. @@ -3780,7 +3731,7 @@ ippSetCollection( * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.6/macOS 10.8@ */ @@ -3789,7 +3740,7 @@ int /* O - 1 on success, 0 on failure */ ippSetDate(ipp_t *ipp, /* I - IPP message */ ipp_attribute_t **attr, /* IO - IPP attribute */ int element, /* I - Value number (0-based) */ - const ipp_uchar_t *datevalue)/* I - Date value */ + const ipp_uchar_t *datevalue)/* I - dateTime value */ { _ipp_value_t *value; /* Current value */ @@ -3798,8 +3749,7 @@ ippSetDate(ipp_t *ipp, /* I - IPP message */ * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_DATE || - element < 0 || element > (*attr)->num_values || !datevalue) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_DATE && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || !datevalue) return (0); /* @@ -3837,7 +3787,7 @@ ippSetGroupTag( ipp_tag_t group_tag) /* I - Group tag */ { /* - * Range check input - group tag must be 0x01 to 0x0F, per RFC 2911... + * Range check input - group tag must be 0x01 to 0x0F, per RFC 8011... */ if (!ipp || !attr || !*attr || @@ -3864,7 +3814,7 @@ ippSetGroupTag( * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.6/macOS 10.8@ */ @@ -3882,9 +3832,7 @@ ippSetInteger(ipp_t *ipp, /* I - IPP message */ * Range check input... */ - if (!ipp || !attr || !*attr || - ((*attr)->value_tag != IPP_TAG_INTEGER && (*attr)->value_tag != IPP_TAG_ENUM) || - element < 0 || element > (*attr)->num_values) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_INTEGER && (*attr)->value_tag != IPP_TAG_ENUM && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values) return (0); /* @@ -3892,7 +3840,12 @@ ippSetInteger(ipp_t *ipp, /* I - IPP message */ */ if ((value = ipp_set_value(ipp, attr, element)) != NULL) + { + if ((*attr)->value_tag != IPP_TAG_ENUM) + (*attr)->value_tag = IPP_TAG_INTEGER; + value->integer = intvalue; + } return (value != NULL); } @@ -3949,7 +3902,7 @@ ippSetName(ipp_t *ipp, /* I - IPP message */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.7/macOS 10.9@ */ @@ -3969,9 +3922,7 @@ ippSetOctetString( * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_STRING || - element < 0 || element > (*attr)->num_values || - datalen < 0 || datalen > IPP_MAX_LENGTH) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_STRING && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || datalen < 0 || datalen > IPP_MAX_LENGTH) return (0); /* @@ -3995,6 +3946,8 @@ ippSetOctetString( * Copy the data... */ + (*attr)->value_tag = IPP_TAG_STRING; + if (value->unknown.data) { /* @@ -4067,7 +4020,7 @@ ippSetOperation(ipp_t *ipp, /* I - IPP request message */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.6/macOS 10.8@ */ @@ -4086,8 +4039,7 @@ ippSetRange(ipp_t *ipp, /* I - IPP message */ * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_RANGE || - element < 0 || element > (*attr)->num_values || lowervalue > uppervalue) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_RANGE && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || lowervalue > uppervalue) return (0); /* @@ -4096,6 +4048,7 @@ ippSetRange(ipp_t *ipp, /* I - IPP message */ if ((value = ipp_set_value(ipp, attr, element)) != NULL) { + (*attr)->value_tag = IPP_TAG_RANGE; value->range.lower = lowervalue; value->range.upper = uppervalue; } @@ -4147,7 +4100,7 @@ ippSetRequestId(ipp_t *ipp, /* I - IPP message */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.6/macOS 10.8@ */ @@ -4168,9 +4121,7 @@ ippSetResolution( * Range check input... */ - if (!ipp || !attr || !*attr || (*attr)->value_tag != IPP_TAG_RESOLUTION || - element < 0 || element > (*attr)->num_values || xresvalue <= 0 || yresvalue <= 0 || - unitsvalue < IPP_RES_PER_INCH || unitsvalue > IPP_RES_PER_CM) + if (!ipp || !attr || !*attr || ((*attr)->value_tag != IPP_TAG_RESOLUTION && (*attr)->value_tag != IPP_TAG_NOVALUE && (*attr)->value_tag != IPP_TAG_UNKNOWN) || element < 0 || element > (*attr)->num_values || xresvalue <= 0 || yresvalue <= 0 || unitsvalue < IPP_RES_PER_INCH || unitsvalue > IPP_RES_PER_CM) return (0); /* @@ -4179,6 +4130,7 @@ ippSetResolution( if ((value = ipp_set_value(ipp, attr, element)) != NULL) { + (*attr)->value_tag = IPP_TAG_RESOLUTION; value->resolution.units = unitsvalue; value->resolution.xres = xresvalue; value->resolution.yres = yresvalue; @@ -4255,7 +4207,7 @@ ippSetStatusCode(ipp_t *ipp, /* I - IPP response or event message */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * @since CUPS 1.6/macOS 10.8@ */ @@ -4268,18 +4220,19 @@ ippSetString(ipp_t *ipp, /* I - IPP message */ { char *temp; /* Temporary string */ _ipp_value_t *value; /* Current value */ + ipp_tag_t value_tag; /* Value tag */ /* * Range check input... */ - if (!ipp || !attr || !*attr || - ((*attr)->value_tag != IPP_TAG_TEXTLANG && - (*attr)->value_tag != IPP_TAG_NAMELANG && - ((*attr)->value_tag < IPP_TAG_TEXT || - (*attr)->value_tag > IPP_TAG_MIMETYPE)) || - element < 0 || element > (*attr)->num_values || !strvalue) + if (attr && *attr) + value_tag = (*attr)->value_tag & IPP_TAG_CUPS_MASK; + else + value_tag = IPP_TAG_ZERO; + + if (!ipp || !attr || !*attr || (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && value_tag != IPP_TAG_NAMELANG && value_tag != IPP_TAG_NOVALUE && value_tag != IPP_TAG_UNKNOWN) || value_tag > IPP_TAG_MIMETYPE || element < 0 || element > (*attr)->num_values || !strvalue) return (0); /* @@ -4288,6 +4241,9 @@ ippSetString(ipp_t *ipp, /* I - IPP message */ if ((value = ipp_set_value(ipp, attr, element)) != NULL) { + if (value_tag == IPP_TAG_NOVALUE || value_tag == IPP_TAG_UNKNOWN) + (*attr)->value_tag = IPP_TAG_KEYWORD; + if (element > 0) value->string.language = (*attr)->values[0].string.language; @@ -4317,7 +4273,7 @@ ippSetString(ipp_t *ipp, /* I - IPP message */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * The @code format@ parameter uses formatting characters compatible with the * printf family of standard functions. Additional arguments follow it as @@ -4355,7 +4311,7 @@ ippSetStringf(ipp_t *ipp, /* I - IPP message */ * The @code attr@ parameter may be modified as a result of setting the value. * * The @code element@ parameter specifies which value to set from 0 to - * @link ippGetCount(attr)@. + * @code ippGetCount(attr)@. * * The @code format@ parameter uses formatting characters compatible with the * printf family of standard functions. Additional arguments follow it as @@ -4388,10 +4344,7 @@ ippSetStringfv(ipp_t *ipp, /* I - IPP message */ else value_tag = IPP_TAG_ZERO; - if (!ipp || !attr || !*attr || - (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && - value_tag != IPP_TAG_NAMELANG) || value_tag > IPP_TAG_MIMETYPE || - !format) + if (!ipp || !attr || !*attr || (value_tag < IPP_TAG_TEXT && value_tag != IPP_TAG_TEXTLANG && value_tag != IPP_TAG_NAMELANG && value_tag != IPP_TAG_NOVALUE && value_tag != IPP_TAG_UNKNOWN) || value_tag > IPP_TAG_MIMETYPE || !format) return (0); /* @@ -4443,6 +4396,8 @@ ippSetStringfv(ipp_t *ipp, /* I - IPP message */ max_bytes = IPP_MAX_CHARSET; break; + case IPP_TAG_NOVALUE : + case IPP_TAG_UNKNOWN : case IPP_TAG_KEYWORD : max_bytes = IPP_MAX_KEYWORD; break; @@ -4698,19 +4653,19 @@ ippSetVersion(ipp_t *ipp, /* I - IPP message */ /* - * 'ippTimeToDate()' - Convert from UNIX time to RFC 1903 format. + * 'ippTimeToDate()' - Convert from time in seconds to RFC 2579 format. */ -const ipp_uchar_t * /* O - RFC-1903 date/time data */ -ippTimeToDate(time_t t) /* I - UNIX time value */ +const ipp_uchar_t * /* O - RFC-2579 date/time data */ +ippTimeToDate(time_t t) /* I - Time in seconds */ { struct tm *unixdate; /* UNIX unixdate/time info */ ipp_uchar_t *date = _cupsGlobals()->ipp_date; - /* RFC-1903 date/time data */ + /* RFC-2579 date/time data */ /* - * RFC-1903 date/time format is: + * RFC-2579 date/time format is: * * Byte(s) Description * ------- ----------- @@ -4750,7 +4705,7 @@ ippTimeToDate(time_t t) /* I - UNIX time value */ * * This function validates the contents of an attribute based on the name and * value tag. 1 is returned if the attribute is valid, 0 otherwise. On - * failure, cupsLastErrorString() is set to a human-readable message. + * failure, @link cupsLastErrorString@ is set to a human-readable message. * * @since CUPS 1.7/macOS 10.9@ */ @@ -4770,21 +4725,6 @@ ippValidateAttribute( ipp_attribute_t *colattr; /* Collection attribute */ regex_t re; /* Regular expression */ ipp_uchar_t *date; /* Current date value */ - static const char * const uri_status_strings[] = - { /* URI status strings */ - "URI too large", - "Bad arguments to function", - "Bad resource in URI", - "Bad port number in URI", - "Bad hostname/address in URI", - "Bad username in URI", - "Bad scheme in URI", - "Bad/empty URI", - "OK", - "Missing scheme in URI", - "Unknown scheme in URI", - "Missing resource in URI" - }; /* @@ -4804,18 +4744,13 @@ ippValidateAttribute( if (*ptr || ptr == attr->name) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad attribute name - invalid character " - "(RFC 2911 section 4.1.3)."), attr->name); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad attribute name - invalid character (RFC 8011 section 5.1.4)."), attr->name); return (0); } if ((ptr - attr->name) > 255) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad attribute name - bad length %d " - "(RFC 2911 section 4.1.3)."), attr->name, - (int)(ptr - attr->name)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad attribute name - bad length %d (RFC 8011 section 5.1.4)."), attr->name, (int)(ptr - attr->name)); return (0); } @@ -4830,10 +4765,7 @@ ippValidateAttribute( if (attr->values[i].boolean != 0 && attr->values[i].boolean != 1) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad boolen value %d " - "(RFC 2911 section 4.1.11)."), attr->name, - attr->values[i].boolean); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad boolean value %d (RFC 8011 section 5.1.21)."), attr->name, attr->values[i].boolean); return (0); } } @@ -4844,10 +4776,7 @@ ippValidateAttribute( { if (attr->values[i].integer < 1) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad enum value %d - out of range " - "(RFC 2911 section 4.1.4)."), attr->name, - attr->values[i].integer); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad enum value %d - out of range (RFC 8011 section 5.1.5)."), attr->name, attr->values[i].integer); return (0); } } @@ -4858,10 +4787,7 @@ ippValidateAttribute( { if (attr->values[i].unknown.length > IPP_MAX_OCTETSTRING) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad octetString value - bad length %d " - "(RFC 2911 section 4.1.10)."), attr->name, - attr->values[i].unknown.length); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad octetString value - bad length %d (RFC 8011 section 5.1.20)."), attr->name, attr->values[i].unknown.length); return (0); } } @@ -4874,73 +4800,55 @@ ippValidateAttribute( if (date[2] < 1 || date[2] > 12) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime month %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[2]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime month %u (RFC 8011 section 5.1.15)."), attr->name, date[2]); return (0); } if (date[3] < 1 || date[3] > 31) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime day %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[3]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime day %u (RFC 8011 section 5.1.15)."), attr->name, date[3]); return (0); } if (date[4] > 23) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime hours %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[4]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime hours %u (RFC 8011 section 5.1.15)."), attr->name, date[4]); return (0); } if (date[5] > 59) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime minutes %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[5]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime minutes %u (RFC 8011 section 5.1.15)."), attr->name, date[5]); return (0); } if (date[6] > 60) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime seconds %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[6]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime seconds %u (RFC 8011 section 5.1.15)."), attr->name, date[6]); return (0); } if (date[7] > 9) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime deciseconds %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[7]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime deciseconds %u (RFC 8011 section 5.1.15)."), attr->name, date[7]); return (0); } if (date[8] != '-' && date[8] != '+') { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime UTC sign '%c' " - "(RFC 2911 section 4.1.14)."), attr->name, date[8]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC sign '%c' (RFC 8011 section 5.1.15)."), attr->name, date[8]); return (0); } if (date[9] > 11) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime UTC hours %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[9]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC hours %u (RFC 8011 section 5.1.15)."), attr->name, date[9]); return (0); } if (date[10] > 59) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad dateTime UTC minutes %u " - "(RFC 2911 section 4.1.14)."), attr->name, date[10]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad dateTime UTC minutes %u (RFC 8011 section 5.1.15)."), attr->name, date[10]); return (0); } } @@ -4951,46 +4859,19 @@ ippValidateAttribute( { if (attr->values[i].resolution.xres <= 0) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad resolution value %dx%d%s - cross " - "feed resolution must be positive " - "(RFC 2911 section 4.1.15)."), attr->name, - attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpcm" : "unknown"); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - cross feed resolution must be positive (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown"); return (0); } if (attr->values[i].resolution.yres <= 0) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad resolution value %dx%d%s - feed " - "resolution must be positive " - "(RFC 2911 section 4.1.15)."), attr->name, - attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpcm" : "unknown"); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - feed resolution must be positive (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown"); return (0); } - if (attr->values[i].resolution.units != IPP_RES_PER_INCH && - attr->values[i].resolution.units != IPP_RES_PER_CM) + if (attr->values[i].resolution.units != IPP_RES_PER_INCH && attr->values[i].resolution.units != IPP_RES_PER_CM) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad resolution value %dx%d%s - bad " - "units value (RFC 2911 section 4.1.15)."), - attr->name, attr->values[i].resolution.xres, - attr->values[i].resolution.yres, - attr->values[i].resolution.units == - IPP_RES_PER_INCH ? "dpi" : - attr->values[i].resolution.units == - IPP_RES_PER_CM ? "dpcm" : "unknown"); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad resolution value %dx%d%s - bad units value (RFC 8011 section 5.1.16)."), attr->name, attr->values[i].resolution.xres, attr->values[i].resolution.yres, attr->values[i].resolution.units == IPP_RES_PER_INCH ? "dpi" : attr->values[i].resolution.units == IPP_RES_PER_CM ? "dpcm" : "unknown"); return (0); } } @@ -5001,11 +4882,7 @@ ippValidateAttribute( { if (attr->values[i].range.lower > attr->values[i].range.upper) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad rangeOfInteger value %d-%d - lower " - "greater than upper (RFC 2911 section 4.1.13)."), - attr->name, attr->values[i].range.lower, - attr->values[i].range.upper); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad rangeOfInteger value %d-%d - lower greater than upper (RFC 8011 section 5.1.14)."), attr->name, attr->values[i].range.lower, attr->values[i].range.upper); return (0); } } @@ -5032,51 +4909,48 @@ ippValidateAttribute( { if ((*ptr & 0xe0) == 0xc0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80) break; + + ptr ++; } else if ((*ptr & 0xf0) == 0xe0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80) break; + + ptr += 2; } else if ((*ptr & 0xf8) == 0xf0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80 || (ptr[3] & 0xc0) != 0x80) break; + + ptr += 3; } else if (*ptr & 0x80) break; + else if ((*ptr < ' ' && *ptr != '\n' && *ptr != '\r' && *ptr != '\t') || *ptr == 0x7f) + break; } - if (*ptr) - { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad text value \"%s\" - bad UTF-8 " - "sequence (RFC 2911 section 4.1.1)."), attr->name, - attr->values[i].string.text); - return (0); - } + if (*ptr) + { + if (*ptr < ' ' || *ptr == 0x7f) + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad control character (PWG 5100.14 section 8.3)."), attr->name, attr->values[i].string.text); + return (0); + } + else + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.2)."), attr->name, attr->values[i].string.text); + return (0); + } + } if ((ptr - attr->values[i].string.text) > (IPP_MAX_TEXT - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad text value \"%s\" - bad length %d " - "(RFC 2911 section 4.1.1)."), attr->name, - attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad text value \"%s\" - bad length %d (RFC 8011 section 5.1.2)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5090,51 +4964,48 @@ ippValidateAttribute( { if ((*ptr & 0xe0) == 0xc0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80) break; + + ptr ++; } else if ((*ptr & 0xf0) == 0xe0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80) break; + + ptr += 2; } else if ((*ptr & 0xf8) == 0xf0) { - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) - break; - ptr ++; - if ((*ptr & 0xc0) != 0x80) + if ((ptr[1] & 0xc0) != 0x80 || (ptr[2] & 0xc0) != 0x80 || (ptr[3] & 0xc0) != 0x80) break; + + ptr += 3; } else if (*ptr & 0x80) break; + else if (*ptr < ' ' || *ptr == 0x7f) + break; } if (*ptr) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad name value \"%s\" - bad UTF-8 " - "sequence (RFC 2911 section 4.1.2)."), attr->name, - attr->values[i].string.text); - return (0); - } + if (*ptr < ' ' || *ptr == 0x7f) + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad control character (PWG 5100.14 section 8.1)."), attr->name, attr->values[i].string.text); + return (0); + } + else + { + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad UTF-8 sequence (RFC 8011 section 5.1.3)."), attr->name, attr->values[i].string.text); + return (0); + } + } if ((ptr - attr->values[i].string.text) > (IPP_MAX_NAME - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad name value \"%s\" - bad length %d " - "(RFC 2911 section 4.1.2)."), attr->name, - attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad name value \"%s\" - bad length %d (RFC 8011 section 5.1.3)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5144,26 +5015,21 @@ ippValidateAttribute( for (i = 0; i < attr->num_values; i ++) { for (ptr = attr->values[i].string.text; *ptr; ptr ++) + { if (!isalnum(*ptr & 255) && *ptr != '-' && *ptr != '.' && *ptr != '_') break; + } if (*ptr || ptr == attr->values[i].string.text) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad keyword value \"%s\" - invalid " - "character (RFC 2911 section 4.1.3)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad keyword value \"%s\" - invalid character (RFC 8011 section 5.1.4)."), attr->name, attr->values[i].string.text); return (0); } if ((ptr - attr->values[i].string.text) > (IPP_MAX_KEYWORD - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad keyword value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.3)."), - attr->name, attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad keyword value \"%s\" - bad length %d (RFC 8011 section 5.1.4)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5172,31 +5038,17 @@ ippValidateAttribute( case IPP_TAG_URI : for (i = 0; i < attr->num_values; i ++) { - uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, - attr->values[i].string.text, - scheme, sizeof(scheme), - userpass, sizeof(userpass), - hostname, sizeof(hostname), - &port, resource, sizeof(resource)); + uri_status = httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource)); if (uri_status < HTTP_URI_STATUS_OK) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad URI value \"%s\" - %s " - "(RFC 2911 section 4.1.5)."), attr->name, - attr->values[i].string.text, - uri_status_strings[uri_status - - HTTP_URI_STATUS_OVERFLOW]); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad URI value \"%s\" - %s (RFC 8011 section 5.1.6)."), attr->name, attr->values[i].string.text, httpURIStatusString(uri_status)); return (0); } if (strlen(attr->values[i].string.text) > (IPP_MAX_URI - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad URI value \"%s\" - bad length %d " - "(RFC 2911 section 4.1.5)."), attr->name, - attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad URI value \"%s\" - bad length %d (RFC 8011 section 5.1.6)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text)); } } break; @@ -5208,27 +5060,22 @@ ippValidateAttribute( if (islower(*ptr & 255)) { for (ptr ++; *ptr; ptr ++) + { if (!islower(*ptr & 255) && !isdigit(*ptr & 255) && *ptr != '+' && *ptr != '-' && *ptr != '.') break; + } } if (*ptr || ptr == attr->values[i].string.text) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad uriScheme value \"%s\" - bad " - "characters (RFC 2911 section 4.1.6)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad uriScheme value \"%s\" - bad characters (RFC 8011 section 5.1.7)."), attr->name, attr->values[i].string.text); return (0); } if ((ptr - attr->values[i].string.text) > (IPP_MAX_URISCHEME - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad uriScheme value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.6)."), - attr->name, attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad uriScheme value \"%s\" - bad length %d (RFC 8011 section 5.1.7)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5238,26 +5085,21 @@ ippValidateAttribute( for (i = 0; i < attr->num_values; i ++) { for (ptr = attr->values[i].string.text; *ptr; ptr ++) + { if (!isprint(*ptr & 255) || isupper(*ptr & 255) || isspace(*ptr & 255)) break; + } if (*ptr || ptr == attr->values[i].string.text) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad charset value \"%s\" - bad " - "characters (RFC 2911 section 4.1.7)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad charset value \"%s\" - bad characters (RFC 8011 section 5.1.8)."), attr->name, attr->values[i].string.text); return (0); } if ((ptr - attr->values[i].string.text) > (IPP_MAX_CHARSET - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad charset value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.7)."), - attr->name, attr->values[i].string.text, - (int)(ptr - attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad charset value \"%s\" - bad length %d (RFC 8011 section 5.1.8)."), attr->name, attr->values[i].string.text, (int)(ptr - attr->values[i].string.text)); return (0); } } @@ -5289,9 +5131,7 @@ ippValidateAttribute( char temp[256]; /* Temporary error string */ regerror(i, &re, temp, sizeof(temp)); - ipp_set_error(IPP_STATUS_ERROR_INTERNAL, - _("Unable to compile naturalLanguage regular " - "expression: %s."), temp); + ipp_set_error(IPP_STATUS_ERROR_INTERNAL, _("Unable to compile naturalLanguage regular expression: %s."), temp); return (0); } @@ -5299,21 +5139,14 @@ ippValidateAttribute( { if (regexec(&re, attr->values[i].string.text, 0, NULL, 0)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad naturalLanguage value \"%s\" - bad " - "characters (RFC 2911 section 4.1.8)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad naturalLanguage value \"%s\" - bad characters (RFC 8011 section 5.1.9)."), attr->name, attr->values[i].string.text); regfree(&re); return (0); } if (strlen(attr->values[i].string.text) > (IPP_MAX_LANGUAGE - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad naturalLanguage value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.8)."), - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad naturalLanguage value \"%s\" - bad length %d (RFC 8011 section 5.1.9)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text)); regfree(&re); return (0); } @@ -5343,9 +5176,7 @@ ippValidateAttribute( char temp[256]; /* Temporary error string */ regerror(i, &re, temp, sizeof(temp)); - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("Unable to compile mimeMediaType regular " - "expression: %s."), temp); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("Unable to compile mimeMediaType regular expression: %s."), temp); return (0); } @@ -5353,21 +5184,14 @@ ippValidateAttribute( { if (regexec(&re, attr->values[i].string.text, 0, NULL, 0)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad mimeMediaType value \"%s\" - bad " - "characters (RFC 2911 section 4.1.9)."), - attr->name, attr->values[i].string.text); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad mimeMediaType value \"%s\" - bad characters (RFC 8011 section 5.1.10)."), attr->name, attr->values[i].string.text); regfree(&re); return (0); } if (strlen(attr->values[i].string.text) > (IPP_MAX_MIMETYPE - 1)) { - ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, - _("\"%s\": Bad mimeMediaType value \"%s\" - bad " - "length %d (RFC 2911 section 4.1.9)."), - attr->name, attr->values[i].string.text, - (int)strlen(attr->values[i].string.text)); + ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST, _("\"%s\": Bad mimeMediaType value \"%s\" - bad length %d (RFC 8011 section 5.1.10)."), attr->name, attr->values[i].string.text, (int)strlen(attr->values[i].string.text)); regfree(&re); return (0); } @@ -5388,8 +5212,8 @@ ippValidateAttribute( * 'ippValidateAttributes()' - Validate all attributes in an IPP message. * * This function validates the contents of the IPP message, including each - * attribute. Like @link ippValidateAttribute@, cupsLastErrorString() is set - * to a human-readable message on failure. + * attribute. Like @link ippValidateAttribute@, @link cupsLastErrorString@ is + * set to a human-readable message on failure. * * @since CUPS 1.7/macOS 10.9@ */ @@ -6385,6 +6209,8 @@ ipp_add_attr(ipp_t *ipp, /* I - IPP message */ * Initialize attribute... */ + DEBUG_printf(("4debug_alloc: %p %s %s%s (%d values)", (void *)attr, name, num_values > 1 ? "1setOf " : "", ippTagString(value_tag), num_values)); + if (name) attr->name = _cupsStrAlloc(name); @@ -6462,6 +6288,7 @@ ipp_free_values(ipp_attribute_t *attr, /* I - Attribute to free values from */ } break; + case IPP_TAG_UNSUPPORTED_VALUE : case IPP_TAG_DEFAULT : case IPP_TAG_UNKNOWN : case IPP_TAG_NOVALUE : @@ -6803,14 +6630,14 @@ ipp_read_http(http_t *http, /* I - Client connection */ if ((bytes = httpRead2(http, (char *)buffer, length - (size_t)tbytes)) < 0) { -#ifdef WIN32 +#ifdef _WIN32 break; #else if (errno != EAGAIN && errno != EINTR) break; bytes = 0; -#endif /* WIN32 */ +#endif /* _WIN32 */ } else if (bytes == 0) break; @@ -6838,11 +6665,11 @@ ipp_read_file(int *fd, /* I - File descriptor */ ipp_uchar_t *buffer, /* O - Read buffer */ size_t length) /* I - Number of bytes to read */ { -#ifdef WIN32 +#ifdef _WIN32 return ((ssize_t)read(*fd, buffer, (unsigned)length)); #else return (read(*fd, buffer, length)); -#endif /* WIN32 */ +#endif /* _WIN32 */ } @@ -6941,6 +6768,11 @@ ipp_set_value(ipp_t *ipp, /* IO - IPP message */ * Reset pointers in the list... */ +#ifndef __clang_analyzer__ + DEBUG_printf(("4debug_free: %p %s", (void *)*attr, temp->name)); +#endif /* !__clang_analyzer__ */ + DEBUG_printf(("4debug_alloc: %p %s %s%s (%d)", (void *)temp, temp->name, temp->num_values > 1 ? "1setOf " : "", ippTagString(temp->value_tag), temp->num_values)); + if (ipp->current == *attr && ipp->prev) { /* @@ -7007,9 +6839,9 @@ ipp_write_file(int *fd, /* I - File descriptor */ ipp_uchar_t *buffer, /* I - Data to write */ size_t length) /* I - Number of bytes to write */ { -#ifdef WIN32 +#ifdef _WIN32 return ((ssize_t)write(*fd, buffer, (unsigned)length)); #else return (write(*fd, buffer, length)); -#endif /* WIN32 */ +#endif /* _WIN32 */ }