diff options
Diffstat (limited to 'Build/source/libs/poppler/poppler-src/poppler/GfxState.cc')
-rw-r--r-- | Build/source/libs/poppler/poppler-src/poppler/GfxState.cc | 77 |
1 files changed, 64 insertions, 13 deletions
diff --git a/Build/source/libs/poppler/poppler-src/poppler/GfxState.cc b/Build/source/libs/poppler/poppler-src/poppler/GfxState.cc index 5d7cc6baa24..157bcf44181 100644 --- a/Build/source/libs/poppler/poppler-src/poppler/GfxState.cc +++ b/Build/source/libs/poppler/poppler-src/poppler/GfxState.cc @@ -72,9 +72,13 @@ GBool Matrix::invertTo(Matrix *other) const { - double det; + const double det_denominator = determinant(); + if (unlikely(det_denominator == 0)) { + *other = {1, 0, 0, 1, 0, 0}; + return gFalse; + } - det = 1 / determinant(); + const double det = 1 / det_denominator; other->m[0] = m[3] * det; other->m[1] = -m[1] * det; other->m[2] = -m[2] * det; @@ -2812,9 +2816,15 @@ void GfxSeparationColorSpace::getRGB(GfxColor *color, GfxRGB *rgb) { } else { x = colToDbl(color->c[0]); func->transform(&x, c); - for (i = 0; i < alt->getNComps(); ++i) { + const int altNComps = alt->getNComps(); + for (i = 0; i < altNComps; ++i) { color2.c[i] = dblToCol(c[i]); } + if (unlikely(altNComps > func->getOutputSize())) { + for (i = func->getOutputSize(); i < altNComps; ++i) { + color2.c[i] = 0; + } + } alt->getRGB(&color2, rgb); } } @@ -3887,7 +3897,7 @@ GfxUnivariateShading::~GfxUnivariateShading() { gfree (cacheBounds); } -void GfxUnivariateShading::getColor(double t, GfxColor *color) { +int GfxUnivariateShading::getColor(double t, GfxColor *color) { double out[gfxColorMaxComps]; // NB: there can be one function with n outputs or n functions with @@ -3897,7 +3907,7 @@ void GfxUnivariateShading::getColor(double t, GfxColor *color) { if (unlikely(nFuncs < 1 || nComps > gfxColorMaxComps)) { for (int i = 0; i < gfxColorMaxComps; i++) color->c[i] = 0; - return; + return gfxColorMaxComps; } if (cacheSize > 0) { @@ -3937,6 +3947,7 @@ void GfxUnivariateShading::getColor(double t, GfxColor *color) { for (int i = 0; i < nComps; ++i) { color->c[i] = dblToCol(out[i]); } + return nComps; } void GfxUnivariateShading::setupCache(const Matrix *ctm, @@ -4059,7 +4070,6 @@ GfxAxialShading *GfxAxialShading::parse(GfxResources *res, Dict *dict, OutputDev int nFuncsA; GBool extend0A, extend1A; Object obj1; - int i; x0A = y0A = x1A = y1A = 0; obj1 = dict->lookup("Coords"); @@ -4098,9 +4108,11 @@ GfxAxialShading *GfxAxialShading::parse(GfxResources *res, Dict *dict, OutputDev error(errSyntaxWarning, -1, "Invalid Function array in shading dictionary"); return nullptr; } - for (i = 0; i < nFuncsA; ++i) { + for (int i = 0; i < nFuncsA; ++i) { Object obj2 = obj1.arrayGet(i); if (!(funcsA[i] = Function::parse(&obj2))) { + for (int j = 0; j < i; ++j) + delete funcsA[j]; return nullptr; } } @@ -4172,7 +4184,13 @@ void GfxAxialShading::getParameterRange(double *lower, double *upper, pdx = x1 - x0; pdy = y1 - y0; - invsqnorm = 1.0 / (pdx * pdx + pdy * pdy); + const double invsqnorm_denominator = (pdx * pdx + pdy * pdy); + if (unlikely(invsqnorm_denominator == 0)) { + *lower = 0; + *upper = 0; + return; + } + invsqnorm = 1.0 / invsqnorm_denominator; pdx *= invsqnorm; pdy *= invsqnorm; @@ -4771,6 +4789,10 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, i error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary"); return nullptr; } + if (unlikely(coordBits <= 0)) { + error(errSyntaxWarning, -1, "Invalid BitsPerCoordinate in shading dictionary"); + return nullptr; + } obj1 = dict->lookup("BitsPerComponent"); if (obj1.isInt()) { compBits = obj1.getInt(); @@ -4778,6 +4800,10 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, i error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary"); return nullptr; } + if (unlikely(compBits <= 0 || compBits > 31)) { + error(errSyntaxWarning, -1, "Invalid BitsPerComponent in shading dictionary"); + return nullptr; + } flagBits = vertsPerRow = 0; // make gcc happy if (typeA == 4) { obj1 = dict->lookup("BitsPerFlag"); @@ -4809,7 +4835,7 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, i for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) { cMin[i] = (obj2 = obj1.arrayGet(4 + 2*i), obj2.getNum(&decodeOk)); cMax[i] = (obj2 = obj1.arrayGet(5 + 2*i), obj2.getNum(&decodeOk)); - cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1); + cMul[i] = (cMax[i] - cMin[i]) / (double)((1u << compBits) - 1); } nComps = i; @@ -5119,6 +5145,10 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di error(errSyntaxWarning, -1, "Missing or invalid BitsPerCoordinate in shading dictionary"); return nullptr; } + if (unlikely(coordBits <= 0)) { + error(errSyntaxWarning, -1, "Invalid BitsPerCoordinate in shading dictionary"); + return nullptr; + } obj1 = dict->lookup("BitsPerComponent"); if (obj1.isInt()) { compBits = obj1.getInt(); @@ -5126,6 +5156,10 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di error(errSyntaxWarning, -1, "Missing or invalid BitsPerComponent in shading dictionary"); return nullptr; } + if (unlikely(compBits <= 0 || compBits > 31)) { + error(errSyntaxWarning, -1, "Invalid BitsPerComponent in shading dictionary"); + return nullptr; + } obj1 = dict->lookup("BitsPerFlag"); if (obj1.isInt()) { flagBits = obj1.getInt(); @@ -5146,7 +5180,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di for (i = 0; 5 + 2*i < obj1.arrayGetLength() && i < gfxColorMaxComps; ++i) { cMin[i] = (obj2 = obj1.arrayGet(4 + 2*i), obj2.getNum(&decodeOk)); cMax[i] = (obj2 = obj1.arrayGet(5 + 2*i), obj2.getNum(&decodeOk)); - cMul[i] = (cMax[i] - cMin[i]) / (double)((1 << compBits) - 1); + cMul[i] = (cMax[i] - cMin[i]) / (double)((1u << compBits) - 1); } nComps = i; @@ -5283,6 +5317,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di case 1: if (nPatchesA == 0) { gfree(patchesA); + for (int k = 0; k < nFuncsA; ++k) delete funcsA[k]; return nullptr; } p->x[0][0] = patchesA[nPatchesA-1].x[0][3]; @@ -5319,6 +5354,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di case 2: if (nPatchesA == 0) { gfree(patchesA); + for (int k = 0; k < nFuncsA; ++k) delete funcsA[k]; return nullptr; } p->x[0][0] = patchesA[nPatchesA-1].x[3][3]; @@ -5355,6 +5391,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di case 3: if (nPatchesA == 0) { gfree(patchesA); + for (int k = 0; k < nFuncsA; ++k) delete funcsA[k]; return nullptr; } p->x[0][0] = patchesA[nPatchesA-1].x[3][0]; @@ -5434,6 +5471,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di case 1: if (nPatchesA == 0) { gfree(patchesA); + for (int k = 0; k < nFuncsA; ++k) delete funcsA[k]; return nullptr; } p->x[0][0] = patchesA[nPatchesA-1].x[0][3]; @@ -5478,6 +5516,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di case 2: if (nPatchesA == 0) { gfree(patchesA); + for (int k = 0; k < nFuncsA; ++k) delete funcsA[k]; return nullptr; } p->x[0][0] = patchesA[nPatchesA-1].x[3][3]; @@ -5522,6 +5561,7 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di case 3: if (nPatchesA == 0) { gfree(patchesA); + for (int k = 0; k < nFuncsA; ++k) delete funcsA[k]; return nullptr; } p->x[0][0] = patchesA[nPatchesA-1].x[3][0]; @@ -5651,7 +5691,7 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, Guchar *indexedLookup; Function *sepFunc; double x[gfxColorMaxComps]; - double y[gfxColorMaxComps]; + double y[gfxColorMaxComps] = {}; int i, j, k; double mapped; GBool useByteLookup; @@ -5677,6 +5717,9 @@ GfxImageColorMap::GfxImageColorMap(int bitsA, Object *decode, } byte_lookup = nullptr; + if (unlikely(bits <= 0)) + goto err1; + // get decode map if (decode->isNull()) { nComps = colorSpace->getNComps(); @@ -6745,10 +6788,18 @@ void GfxState::setPath(GfxPath *pathA) { void GfxState::getUserClipBBox(double *xMin, double *yMin, double *xMax, double *yMax) { double ictm[6]; - double xMin1, yMin1, xMax1, yMax1, det, tx, ty; + double xMin1, yMin1, xMax1, yMax1, tx, ty; // invert the CTM - det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + const double det_denominator = (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + if (unlikely(det_denominator == 0)) { + *xMin = 0; + *yMin = 0; + *xMax = 0; + *yMax = 0; + return; + } + const double det = 1 / det_denominator; ictm[0] = ctm[3] * det; ictm[1] = -ctm[1] * det; ictm[2] = -ctm[2] * det; |