diff --git a/cups/ipp.c b/cups/ipp.c index 2ed8f95ba..51b19ad8d 100644 --- a/cups/ipp.c +++ b/cups/ipp.c @@ -1092,7 +1092,8 @@ ippAddStringfv(ipp_t *ipp, // I - IPP message bufptr --; } - bufptr --; + if (bufptr > buffer) + bufptr --; } *bufptr = '\0'; @@ -3434,7 +3435,8 @@ ippSetStringfv(ipp_t *ipp, // I - IPP message bufptr --; } - bufptr --; + if (bufptr > buffer) + bufptr --; } *bufptr = '\0'; diff --git a/cups/testipp.c b/cups/testipp.c index a828fd6d6..24c25a3d6 100644 --- a/cups/testipp.c +++ b/cups/testipp.c @@ -893,6 +893,34 @@ main(int argc, // I - Number of command-line arguments testEnd(true); } + // Oversized values consisting only of UTF-8 continuation bytes must be + // truncated to a boundary without stepping below the format buffer... + testBegin("ippAddStringf(oversized continuation bytes)"); + { + char overlong[2 * IPP_MAX_NAME]; + const char *str; // Resulting value + + memset(overlong, 0x80, sizeof(overlong) - 1); + overlong[sizeof(overlong) - 1] = '\0'; + + attr = ippAddStringf(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "overlong-attr", /*lang*/NULL, "%s", overlong); + + if (!attr) + { + testEndMessage(false, "Unable to create name attribute"); + status = 1; + } + else if ((str = ippGetString(attr, 0, NULL)) == NULL || strlen(str) >= IPP_MAX_NAME) + { + testEndMessage(false, "value not truncated (%d bytes)", str ? (int)strlen(str) : -1); + status = 1; + } + else + { + testEnd(true); + } + } + ippDelete(request); #ifdef DEBUG