]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/ipp.c
License change: Apache License, Version 2.0.
[thirdparty/cups.git] / cups / ipp.c
index 1964962ce4c6c91e90bb5ee68cd5cebd03d398ee..58f120c0f6b9bd1d4d4047080128603830c43214 100644 (file)
@@ -1,16 +1,10 @@
 /*
  * Internet Printing Protocol functions for CUPS.
  *
- * Copyright 2007-2015 by Apple Inc.
+ * Copyright 2007-2017 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.
  */
 
 /*
@@ -316,7 +310,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 +1374,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 +1413,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 +1441,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);
@@ -1495,6 +1503,16 @@ ippCopyAttribute(
         dstattr = ippAddSeparator(dst);
        break;
 
+    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, srcattr->value_tag & ~IPP_TAG_CUPS_CONST, srcattr->name);
+        break;
+
     case IPP_TAG_INTEGER :
     case IPP_TAG_ENUM :
         dstattr = ippAddIntegers(dst, srcattr->group_tag, srcattr->value_tag,
@@ -1745,12 +1763,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 +1780,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 +1832,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 +1881,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 +2165,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 +2194,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 +2245,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 +2301,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 +2354,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 +2417,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 +2479,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 +2573,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 +2583,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 +2638,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 +2718,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 +2737,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 +2801,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@
@@ -3689,7 +3721,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 +3763,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 +3804,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 +3812,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 +3821,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 */
 
@@ -3837,7 +3869,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 +3896,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@
  */
@@ -3949,7 +3981,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@
  */
@@ -4067,7 +4099,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@
  */
@@ -4147,7 +4179,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@
  */
@@ -4255,7 +4287,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@
  */
@@ -4317,7 +4349,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 +4387,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
@@ -4698,19 +4730,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 +4782,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@
  */
@@ -4806,7 +4838,7 @@ ippValidateAttribute(
   {
     ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                   _("\"%s\": Bad attribute name - invalid character "
-                   "(RFC 2911 section 4.1.3)."), attr->name);
+                   "(RFC 8011 section 5.1.4)."), attr->name);
     return (0);
   }
 
@@ -4814,7 +4846,7 @@ ippValidateAttribute(
   {
     ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                   _("\"%s\": Bad attribute name - bad length %d "
-                   "(RFC 2911 section 4.1.3)."), attr->name,
+                   "(RFC 8011 section 5.1.4)."), attr->name,
                  (int)(ptr - attr->name));
     return (0);
   }
@@ -4832,7 +4864,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                           _("\"%s\": Bad boolen value %d "
-                           "(RFC 2911 section 4.1.11)."), attr->name,
+                           "(RFC 8011 section 5.1.21)."), attr->name,
                          attr->values[i].boolean);
            return (0);
          }
@@ -4846,7 +4878,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad enum value %d - out of range "
-                           "(RFC 2911 section 4.1.4)."), attr->name,
+                           "(RFC 8011 section 5.1.5)."), attr->name,
                            attr->values[i].integer);
             return (0);
          }
@@ -4860,7 +4892,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad octetString value - bad length %d "
-                           "(RFC 2911 section 4.1.10)."), attr->name,
+                           "(RFC 8011 section 5.1.20)."), attr->name,
                            attr->values[i].unknown.length);
            return (0);
          }
@@ -4876,7 +4908,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime month %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[2]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[2]);
            return (0);
          }
 
@@ -4884,7 +4916,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime day %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[3]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[3]);
            return (0);
          }
 
@@ -4892,7 +4924,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime hours %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[4]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[4]);
            return (0);
          }
 
@@ -4900,7 +4932,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime minutes %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[5]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[5]);
            return (0);
          }
 
@@ -4908,7 +4940,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime seconds %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[6]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[6]);
            return (0);
          }
 
@@ -4916,7 +4948,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime deciseconds %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[7]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[7]);
            return (0);
          }
 
@@ -4924,7 +4956,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime UTC sign '%c' "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[8]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[8]);
            return (0);
          }
 
@@ -4932,7 +4964,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime UTC hours %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[9]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[9]);
            return (0);
          }
 
@@ -4940,7 +4972,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad dateTime UTC minutes %u "
-                           "(RFC 2911 section 4.1.14)."), attr->name, date[10]);
+                           "(RFC 8011 section 5.1.15)."), attr->name, date[10]);
            return (0);
          }
        }
@@ -4954,7 +4986,7 @@ ippValidateAttribute(
            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,
+                           "(RFC 8011 section 5.1.16)."), attr->name,
                          attr->values[i].resolution.xres,
                          attr->values[i].resolution.yres,
                          attr->values[i].resolution.units ==
@@ -4969,7 +5001,7 @@ ippValidateAttribute(
            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,
+                           "(RFC 8011 section 5.1.16)."), attr->name,
                          attr->values[i].resolution.xres,
                          attr->values[i].resolution.yres,
                          attr->values[i].resolution.units ==
@@ -4984,7 +5016,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad resolution value %dx%d%s - bad "
-                           "units value (RFC 2911 section 4.1.15)."),
+                           "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 ==
@@ -5003,7 +5035,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad rangeOfInteger value %d-%d - lower "
-                           "greater than upper (RFC 2911 section 4.1.13)."),
+                           "greater than upper (RFC 8011 section 5.1.14)."),
                          attr->name, attr->values[i].range.lower,
                          attr->values[i].range.upper);
            return (0);
@@ -5065,7 +5097,7 @@ ippValidateAttribute(
          {
            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,
+                           "sequence (RFC 8011 section 5.1.2)."), attr->name,
                          attr->values[i].string.text);
            return (0);
          }
@@ -5074,7 +5106,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad text value \"%s\" - bad length %d "
-                           "(RFC 2911 section 4.1.1)."), attr->name,
+                           "(RFC 8011 section 5.1.2)."), attr->name,
                          attr->values[i].string.text,
                          (int)(ptr - attr->values[i].string.text));
            return (0);
@@ -5123,7 +5155,7 @@ ippValidateAttribute(
          {
            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,
+                           "sequence (RFC 8011 section 5.1.3)."), attr->name,
                          attr->values[i].string.text);
            return (0);
          }
@@ -5132,7 +5164,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad name value \"%s\" - bad length %d "
-                           "(RFC 2911 section 4.1.2)."), attr->name,
+                           "(RFC 8011 section 5.1.3)."), attr->name,
                          attr->values[i].string.text,
                          (int)(ptr - attr->values[i].string.text));
            return (0);
@@ -5152,7 +5184,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad keyword value \"%s\" - invalid "
-                           "character (RFC 2911 section 4.1.3)."),
+                           "character (RFC 8011 section 5.1.4)."),
                          attr->name, attr->values[i].string.text);
            return (0);
          }
@@ -5161,7 +5193,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad keyword value \"%s\" - bad "
-                           "length %d (RFC 2911 section 4.1.3)."),
+                           "length %d (RFC 8011 section 5.1.4)."),
                          attr->name, attr->values[i].string.text,
                          (int)(ptr - attr->values[i].string.text));
            return (0);
@@ -5183,7 +5215,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad URI value \"%s\" - %s "
-                           "(RFC 2911 section 4.1.5)."), attr->name,
+                           "(RFC 8011 section 5.1.6)."), attr->name,
                          attr->values[i].string.text,
                          uri_status_strings[uri_status -
                                             HTTP_URI_STATUS_OVERFLOW]);
@@ -5194,7 +5226,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad URI value \"%s\" - bad length %d "
-                           "(RFC 2911 section 4.1.5)."), attr->name,
+                           "(RFC 8011 section 5.1.6)."), attr->name,
                          attr->values[i].string.text,
                          (int)strlen(attr->values[i].string.text));
          }
@@ -5217,7 +5249,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad uriScheme value \"%s\" - bad "
-                           "characters (RFC 2911 section 4.1.6)."),
+                           "characters (RFC 8011 section 5.1.7)."),
                          attr->name, attr->values[i].string.text);
            return (0);
          }
@@ -5226,7 +5258,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad uriScheme value \"%s\" - bad "
-                           "length %d (RFC 2911 section 4.1.6)."),
+                           "length %d (RFC 8011 section 5.1.7)."),
                          attr->name, attr->values[i].string.text,
                          (int)(ptr - attr->values[i].string.text));
            return (0);
@@ -5246,7 +5278,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad charset value \"%s\" - bad "
-                           "characters (RFC 2911 section 4.1.7)."),
+                           "characters (RFC 8011 section 5.1.8)."),
                          attr->name, attr->values[i].string.text);
            return (0);
          }
@@ -5255,7 +5287,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad charset value \"%s\" - bad "
-                           "length %d (RFC 2911 section 4.1.7)."),
+                           "length %d (RFC 8011 section 5.1.8)."),
                          attr->name, attr->values[i].string.text,
                          (int)(ptr - attr->values[i].string.text));
            return (0);
@@ -5301,7 +5333,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad naturalLanguage value \"%s\" - bad "
-                           "characters (RFC 2911 section 4.1.8)."),
+                           "characters (RFC 8011 section 5.1.9)."),
                          attr->name, attr->values[i].string.text);
            regfree(&re);
            return (0);
@@ -5311,7 +5343,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad naturalLanguage value \"%s\" - bad "
-                           "length %d (RFC 2911 section 4.1.8)."),
+                           "length %d (RFC 8011 section 5.1.9)."),
                          attr->name, attr->values[i].string.text,
                          (int)strlen(attr->values[i].string.text));
            regfree(&re);
@@ -5355,7 +5387,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad mimeMediaType value \"%s\" - bad "
-                           "characters (RFC 2911 section 4.1.9)."),
+                           "characters (RFC 8011 section 5.1.10)."),
                          attr->name, attr->values[i].string.text);
            regfree(&re);
            return (0);
@@ -5365,7 +5397,7 @@ ippValidateAttribute(
          {
            ipp_set_error(IPP_STATUS_ERROR_BAD_REQUEST,
                          _("\"%s\": Bad mimeMediaType value \"%s\" - bad "
-                           "length %d (RFC 2911 section 4.1.9)."),
+                           "length %d (RFC 8011 section 5.1.10)."),
                          attr->name, attr->values[i].string.text,
                          (int)strlen(attr->values[i].string.text));
            regfree(&re);
@@ -5388,8 +5420,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 +6417,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);
 
@@ -6941,6 +6975,9 @@ ipp_set_value(ipp_t           *ipp,       /* IO - IPP message */
     * Reset pointers in the list...
     */
 
+    DEBUG_printf(("4debug_free: %p %s", (void *)*attr, temp->name));
+    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)
     {
      /*