summaryrefslogtreecommitdiff
path: root/cups/ipp-file.c
diff options
context:
space:
mode:
authorMichael R Sweet <michael.r.sweet@gmail.com>2019-05-13 16:24:19 -0400
committerMichael R Sweet <michael.r.sweet@gmail.com>2019-05-13 16:24:19 -0400
commitbd5165714864567d6626b0fabacdd4ac56498307 (patch)
treeafee848f5655aba81f906570c007a77969704435 /cups/ipp-file.c
parente1074f486d6d248e58e2602d1802d99d3e5439b0 (diff)
downloadcups-bd5165714864567d6626b0fabacdd4ac56498307.tar.gz
Support <hex> strings in IPP files.
Diffstat (limited to 'cups/ipp-file.c')
-rw-r--r--cups/ipp-file.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/cups/ipp-file.c b/cups/ipp-file.c
index 0bba21d51..ea991b529 100644
--- a/cups/ipp-file.c
+++ b/cups/ipp-file.c
@@ -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 :