]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/ipp-file.c
Update ipp documentation to reflect the behavior of configuring WiFi on IPP USB printers.
[thirdparty/cups.git] / cups / ipp-file.c
index 0bba21d518c67b7bad5b9011f1128f49cab33729..5483a607df600c4752114e6745d978dc8086449d 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * IPP data file parsing functions.
  *
- * Copyright © 2007-2018 by Apple Inc.
+ * Copyright © 2007-2019 by Apple Inc.
  * Copyright © 1997-2007 by Easy Software Products.
  *
  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
@@ -459,14 +459,14 @@ parse_collection(
 
       if (!_ippFileReadToken(f, syntax, sizeof(syntax)))
       {
-        report_error(f, v, user_data, "Missing ATTR syntax on line %d of \"%s\".", f->linenum, f->filename);
+        report_error(f, v, user_data, "Missing MEMBER syntax on line %d of \"%s\".", f->linenum, f->filename);
        ippDelete(col);
        col = NULL;
        break;
       }
       else if ((value_tag = ippTagValue(syntax)) < IPP_TAG_UNSUPPORTED_VALUE)
       {
-        report_error(f, v, user_data, "Bad ATTR syntax \"%s\" on line %d of \"%s\".", syntax, f->linenum, f->filename);
+        report_error(f, v, user_data, "Bad MEMBER syntax \"%s\" on line %d of \"%s\".", syntax, f->linenum, f->filename);
        ippDelete(col);
        col = NULL;
        break;
@@ -474,7 +474,7 @@ parse_collection(
 
       if (!_ippFileReadToken(f, name, sizeof(name)) || !name[0])
       {
-        report_error(f, v, user_data, "Missing ATTR name on line %d of \"%s\".", f->linenum, f->filename);
+        report_error(f, v, user_data, "Missing MEMBER name on line %d of \"%s\".", f->linenum, f->filename);
        ippDelete(col);
        col = NULL;
        break;
@@ -549,8 +549,11 @@ parse_value(_ipp_file_t      *f,   /* I  - IPP data file */
             ipp_attribute_t  **attr,   /* IO - IPP attribute */
             int              element)  /* I  - Element number */
 {
-  char value[1024],                    /* Value string */
-       temp[1024];                     /* Temporary string */
+  char         value[2049],            /* Value string */
+               *valueptr,              /* Pointer into value string */
+               temp[2049],             /* Temporary string */
+               *tempptr;               /* Pointer into temporary string */
+  size_t       valuelen;               /* Length of value */
 
 
   if (!_ippFileReadToken(f, temp, sizeof(temp)))
@@ -565,12 +568,10 @@ parse_value(_ipp_file_t      *f,  /* I  - IPP data file */
   {
     case IPP_TAG_BOOLEAN :
         return (ippSetBoolean(ipp, attr, element, !_cups_strcasecmp(value, "true")));
-        break;
 
     case IPP_TAG_ENUM :
     case IPP_TAG_INTEGER :
         return (ippSetInteger(ipp, attr, element, (int)strtol(value, NULL, 0)));
-        break;
 
     case IPP_TAG_DATE :
         {
@@ -583,8 +584,80 @@ parse_value(_ipp_file_t      *f,   /* I  - IPP data file */
                utc_offset = 0;         /* Timezone offset from UTC */
           ipp_uchar_t date[11];                /* dateTime value */
 
-          if (sscanf(value, "%d-%d-%dT%d:%d:%d%d", &year, &month, &day, &hour, &minute, &second, &utc_offset) < 6)
+          if (*value == 'P')
+          {
+           /*
+            * Time period...
+            */
+
+            time_t     curtime;        /* Current time in seconds */
+            int                period = 0,     /* Current period value */
+                       saw_T = 0;      /* Saw time separator */
+
+            curtime = time(NULL);
+
+            for (valueptr = value + 1; *valueptr; valueptr ++)
+            {
+              if (isdigit(*valueptr & 255))
+              {
+                period = (int)strtol(valueptr, &valueptr, 10);
+
+                if (!valueptr || period < 0)
+                {
+                 report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
+                 return (0);
+               }
+              }
+
+              if (*valueptr == 'Y')
+              {
+                curtime += 365 * 86400 * period;
+                period  = 0;
+              }
+              else if (*valueptr == 'M')
+              {
+                if (saw_T)
+                  curtime += 60 * period;
+                else
+                  curtime += 30 * 86400 * period;
+
+                period = 0;
+              }
+              else if (*valueptr == 'D')
+              {
+                curtime += 86400 * period;
+                period  = 0;
+              }
+              else if (*valueptr == 'H')
+              {
+                curtime += 3600 * period;
+                period  = 0;
+              }
+              else if (*valueptr == 'S')
+              {
+                curtime += period;
+                period = 0;
+              }
+              else if (*valueptr == 'T')
+              {
+                saw_T  = 1;
+                period = 0;
+              }
+              else
+             {
+               report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
+               return (0);
+             }
+           }
+
+           return (ippSetDate(ipp, attr, element, ippTimeToDate(curtime)));
+          }
+          else if (sscanf(value, "%d-%d-%dT%d:%d:%d%d", &year, &month, &day, &hour, &minute, &second, &utc_offset) < 6)
           {
+           /*
+            * Date/time value did not parse...
+            */
+
            report_error(f, v, user_data, "Bad dateTime value \"%s\" on line %d of \"%s\".", value, f->linenum, f->filename);
            return (0);
           }
@@ -612,7 +685,6 @@ parse_value(_ipp_file_t      *f,    /* I  - IPP data file */
 
           return (ippSetDate(ipp, attr, element, date));
         }
-        break;
 
     case IPP_TAG_RESOLUTION :
        {
@@ -640,7 +712,6 @@ parse_value(_ipp_file_t      *f,    /* I  - IPP data file */
          else
            return (ippSetResolution(ipp, attr, element, (ipp_res_t)0, xres, yres));
        }
-       break;
 
     case IPP_TAG_RANGE :
        {
@@ -655,11 +726,46 @@ parse_value(_ipp_file_t      *f,  /* I  - IPP data file */
 
          return (ippSetRange(ipp, attr, element, lower, upper));
        }
-       break;
 
     case IPP_TAG_STRING :
-        return (ippSetOctetString(ipp, attr, element, value, (int)strlen(value)));
-        break;
+        valuelen = strlen(value);
+
+        if (value[0] == '<' && value[strlen(value) - 1] == '>')
+        {
+          if (valuelen & 1)
+          {
+           report_error(f, v, user_data, "Bad octetString value on line %d of \"%s\".", f->linenum, f->filename);
+           return (0);
+          }
+
+          valueptr = value + 1;
+          tempptr  = temp;
+
+          while (*valueptr && *valueptr != '>')
+          {
+           if (!isxdigit(valueptr[0] & 255) || !isxdigit(valueptr[1] & 255))
+           {
+             report_error(f, v, user_data, "Bad octetString value on line %d of \"%s\".", f->linenum, f->filename);
+             return (0);
+           }
+
+            if (valueptr[0] >= '0' && valueptr[0] <= '9')
+              *tempptr = (char)((valueptr[0] - '0') << 4);
+           else
+              *tempptr = (char)((tolower(valueptr[0]) - 'a' + 10) << 4);
+
+            if (valueptr[1] >= '0' && valueptr[1] <= '9')
+              *tempptr |= (valueptr[1] - '0');
+           else
+              *tempptr |= (tolower(valueptr[1]) - 'a' + 10);
+
+            tempptr ++;
+          }
+
+          return (ippSetOctetString(ipp, attr, element, temp, (int)(tempptr - temp)));
+        }
+        else
+          return (ippSetOctetString(ipp, attr, element, value, (int)valuelen));
 
     case IPP_TAG_TEXTLANG :
     case IPP_TAG_NAMELANG :
@@ -672,7 +778,6 @@ parse_value(_ipp_file_t      *f,    /* I  - IPP data file */
     case IPP_TAG_LANGUAGE :
     case IPP_TAG_MIMETYPE :
         return (ippSetString(ipp, attr, element, value));
-        break;
 
     case IPP_TAG_BEGIN_COLLECTION :
         {
@@ -681,7 +786,7 @@ parse_value(_ipp_file_t      *f,    /* I  - IPP data file */
 
           if (strcmp(value, "{"))
           {
-           report_error(f, v, user_data, "Bad ATTR collection value on line %d of \"%s\".", f->linenum, f->filename);
+           report_error(f, v, user_data, "Bad collection value on line %d of \"%s\".", f->linenum, f->filename);
            return (0);
           }
 
@@ -693,14 +798,11 @@ parse_value(_ipp_file_t      *f,  /* I  - IPP data file */
 
          return (status);
        }
-       break;
 
     default :
-        report_error(f, v, user_data, "Unsupported ATTR value on line %d of \"%s\".", f->linenum, f->filename);
+        report_error(f, v, user_data, "Unsupported value on line %d of \"%s\".", f->linenum, f->filename);
         return (0);
   }
-
-  return (1);
 }