diff --git a/CHANGES.md b/CHANGES.md index d81135b1e..e996dd924 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -24,6 +24,7 @@ v3.0.4 - YYYY-MM-DD - Fixed `cupsSignCredentialsRequest` to reject requests with a bad signature (Issue 172) - Fixed `httpPeek` return value with compressed message bodies (Issue #175) +- Fixed integer overflow when parsing over-large media size names. - Fixed an issue with `cupsGetCredentialsTrust` for credentials that are signed by an unknown CA. - Fixed PAM support in `ippeveprinter`. diff --git a/cups/pwg-media.c b/cups/pwg-media.c index d3a40a41c..bc583c547 100644 --- a/cups/pwg-media.c +++ b/cups/pwg-media.c @@ -1054,15 +1054,22 @@ pwg_scan_measurement( int numer, // I - Numerator from units int denom) // I - Denominator from units { - int value = 0, // Measurement value - fractional = 0, // Fractional value - divisor = 1, // Fractional divisor - digits = 10 * numer * denom; // Maximum fractional value to read + long long value = 0, // Measurement value + fractional = 0, // Fractional value + divisor = 1, // Fractional divisor + digits = 10LL * numer * denom; + // Maximum fractional value to read - // Scan integer portion... + // Scan integer portion, ignoring any digits beyond the range of the return + // value... while (*buf >= '0' && *buf <= '9') - value = value * 10 + (*buf++) - '0'; + { + if (value < INT_MAX) + value = value * 10 + *buf - '0'; + + buf ++; + } if (*buf == '.') { @@ -1083,5 +1090,7 @@ pwg_scan_measurement( if (bufptr) *bufptr = (char *)buf; - return (value * numer / denom + fractional * numer / denom / divisor); + value = value * numer / denom + fractional * numer / denom / divisor; + + return (value < INT_MAX ? (int)value : INT_MAX); } diff --git a/cups/testpwg.c b/cups/testpwg.c index 155032422..a8b8c7e7b 100644 --- a/cups/testpwg.c +++ b/cups/testpwg.c @@ -68,6 +68,22 @@ main(int argc, // I - Number of command-line args else testEndMessage(true, "%dx%d", pwg->width, pwg->length); + testBegin("pwgMediaForPWG(\"custom_max_1000000x1000000in\")"); + if ((pwg = pwgMediaForPWG("custom_max_1000000x1000000in")) == NULL) + testEndMessage(false, "not found"); + else if (pwg->width <= 0 || pwg->length <= 0) + testEndMessage(false, "%dx%d", pwg->width, pwg->length); + else + testEndMessage(true, "%dx%d", pwg->width, pwg->length); + + testBegin("pwgMediaForPWG(\"custom_max_9999999999x9999999999mm\")"); + if ((pwg = pwgMediaForPWG("custom_max_9999999999x9999999999mm")) == NULL) + testEndMessage(false, "not found"); + else if (pwg->width <= 0 || pwg->length <= 0) + testEndMessage(false, "%dx%d", pwg->width, pwg->length); + else + testEndMessage(true, "%dx%d", pwg->width, pwg->length); + testBegin("pwgMediaForPWG(\"disc_test_10x100mm\")"); if ((pwg = pwgMediaForPWG("disc_test_10x100mm")) == NULL) testEndMessage(false, "not found");