]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - cups/ipp-file.c
Support <hex> strings in IPP files.
[thirdparty/cups.git] / cups / ipp-file.c
index 0bba21d518c67b7bad5b9011f1128f49cab33729..ea991b529553c559df08c0a91f94daf45c2b4a3f 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
@@ -297,13 +297,16 @@ _ippFileReadToken(_ipp_file_t *f, /* I - File to read from */
       DEBUG_printf(("1_ippFileReadToken: Returning \"%s\" before whitespace.", token));
       return (1);
     }
-    else if (!quote && (ch == '\'' || ch == '\"'))
+    else if (!quote && (ch == '\'' || ch == '\"' || ch == '<'))
     {
      /*
       * Start of quoted text or regular expression...
       */
 
-      quote = ch;
+      if (ch == '<')
+        quote = '>';
+      else
+        quote = ch;
 
       DEBUG_printf(("1_ippFileReadToken: Start of quoted string, quote=%c, pos=%ld", quote, (long)cupsFileTell(f->fp)));
     }
@@ -382,23 +385,26 @@ _ippFileReadToken(_ipp_file_t *f, /* I - File to read from */
          ch = '\v';
       }
 
-      if (tokptr < tokend)
+      if (quote != '>' || !isspace(ch & 255))
       {
-       /*
-       * Add to current token...
-       */
+       if (tokptr < tokend)
+       {
+        /*
+         * Add to current token...
+         */
 
-       *tokptr++ = (char)ch;
-      }
-      else
-      {
-       /*
-       * Token too long...
-       */
+         *tokptr++ = (char)ch;
+       }
+       else
+       {
+        /*
+         * Token too long...
+         */
 
-       *tokptr = '\0';
-       DEBUG_printf(("1_ippFileReadToken: Too long: \"%s\".", token));
-       return (0);
+         *tokptr = '\0';
+         DEBUG_printf(("1_ippFileReadToken: Too long: \"%s\".", token));
+         return (0);
+       }
       }
     }
 
@@ -549,8 +555,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)))
@@ -658,7 +667,44 @@ parse_value(_ipp_file_t      *f,   /* I  - IPP data file */
        break;
 
     case IPP_TAG_STRING :
-        return (ippSetOctetString(ipp, attr, element, value, (int)strlen(value)));
+        valuelen = strlen(value);
+
+        if (value[0] == '<' && value[strlen(value) - 1] == '>')
+        {
+          if (valuelen & 1)
+          {
+           report_error(f, v, user_data, "Bad ATTR 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 ATTR 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));
         break;
 
     case IPP_TAG_TEXTLANG :