/*
* 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
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;
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;
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)))
{
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 :
{
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);
}
return (ippSetDate(ipp, attr, element, date));
}
- break;
case IPP_TAG_RESOLUTION :
{
else
return (ippSetResolution(ipp, attr, element, (ipp_res_t)0, xres, yres));
}
- break;
case IPP_TAG_RANGE :
{
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 :
case IPP_TAG_LANGUAGE :
case IPP_TAG_MIMETYPE :
return (ippSetString(ipp, attr, element, value));
- break;
case IPP_TAG_BEGIN_COLLECTION :
{
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);
}
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);
}