diff options
author | Michael R Sweet <michael.r.sweet@gmail.com> | 2019-05-13 16:24:19 -0400 |
---|---|---|
committer | Michael R Sweet <michael.r.sweet@gmail.com> | 2019-05-13 16:24:19 -0400 |
commit | bd5165714864567d6626b0fabacdd4ac56498307 (patch) | |
tree | afee848f5655aba81f906570c007a77969704435 /cups/ipp-file.c | |
parent | e1074f486d6d248e58e2602d1802d99d3e5439b0 (diff) | |
download | cups-bd5165714864567d6626b0fabacdd4ac56498307.tar.gz |
Support <hex> strings in IPP files.
Diffstat (limited to 'cups/ipp-file.c')
-rw-r--r-- | cups/ipp-file.c | 86 |
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 : |