https://bugs.gentoo.org/941933 From 22304ae8034d067670a9f95022083a75fac92b4c Mon Sep 17 00:00:00 2001 From: PBS Date: Tue, 22 Oct 2024 14:48:31 +0100 Subject: [PATCH] Future-proof against poppler 24.10 changes --- .../internal/pdfinput/pdf-parser.cpp | 120 ++++++++---------- src/extension/internal/pdfinput/pdf-parser.h | 4 +- .../pdfinput/poppler-transition-api.h | 6 + 3 files changed, 61 insertions(+), 69 deletions(-) diff --git a/src/extension/internal/pdfinput/pdf-parser.cpp b/src/extension/internal/pdfinput/pdf-parser.cpp index 97b2909218a..28000a87b0c 100644 --- a/src/extension/internal/pdfinput/pdf-parser.cpp +++ b/src/extension/internal/pdfinput/pdf-parser.cpp @@ -817,11 +817,11 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) _POPPLER_FREE(obj3); if (_POPPLER_CALL_ARGS_DEREF(obj3, obj2.dictLookup, "G").isStream()) { if (_POPPLER_CALL_ARGS_DEREF(obj4, obj3.streamGetDict()->lookup, "Group").isDict()) { - GfxColorSpace *blendingColorSpace = nullptr; + std::unique_ptr blendingColorSpace; GBool isolated = gFalse; GBool knockout = gFalse; if (!_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup, "CS").isNull()) { - blendingColorSpace = GfxColorSpace::parse(nullptr, &obj5, nullptr, state); + blendingColorSpace = std::unique_ptr(GfxColorSpace::parse(nullptr, &obj5, nullptr, state)); } _POPPLER_FREE(obj5); if (_POPPLER_CALL_ARGS_DEREF(obj5, obj4.dictLookup, "I").isBool()) { @@ -842,7 +842,7 @@ void PdfParser::opSetExtGState(Object args[], int /*numArgs*/) } } } - doSoftMask(&obj3, alpha, blendingColorSpace, isolated, knockout, funcs[0], &backdropColor); + doSoftMask(&obj3, alpha, blendingColorSpace.get(), isolated, knockout, funcs[0], &backdropColor); if (funcs[0]) { delete funcs[0]; } @@ -927,9 +927,6 @@ void PdfParser::doSoftMask(Object *str, GBool alpha, alpha, transferFunc, backdropColor); --formDepth; - if (blendingColorSpace) { - delete blendingColorSpace; - } _POPPLER_FREE(obj1); } @@ -946,42 +943,43 @@ void PdfParser::opSetRenderingIntent(Object /*args*/[], int /*numArgs*/) * * Maintains a cache for named color spaces to avoid expensive re-parsing. */ -GfxColorSpace *PdfParser::lookupColorSpaceCopy(Object &arg) +std::unique_ptr PdfParser::lookupColorSpaceCopy(Object &arg) { assert(!arg.isNull()); - GfxColorSpace *colorSpace = nullptr; if (char const *name = arg.isName() ? arg.getName() : nullptr) { auto const cache_name = std::to_string(formDepth) + "-" + name; - if ((colorSpace = colorSpacesCache[cache_name].get())) { - return colorSpace->copy(); + if (auto cached = colorSpacesCache[cache_name].get()) { + return std::unique_ptr(cached->copy()); } - Object obj = res->lookupColorSpace(name); - if (obj.isNull()) { - colorSpace = GfxColorSpace::parse(res, &arg, nullptr, state); + std::unique_ptr colorSpace; + if (auto obj = res->lookupColorSpace(name); !obj.isNull()) { + colorSpace = std::unique_ptr(GfxColorSpace::parse(res, &obj, nullptr, state)); } else { - colorSpace = GfxColorSpace::parse(res, &obj, nullptr, state); + colorSpace = std::unique_ptr(GfxColorSpace::parse(res, &arg, nullptr, state)); } if (colorSpace && colorSpace->getMode() != csPattern) { - colorSpacesCache[cache_name].reset(colorSpace->copy()); + colorSpacesCache[cache_name] = std::unique_ptr(colorSpace->copy()); } + + return colorSpace; } else { // We were passed in an object directly. - colorSpace = GfxColorSpace::parse(res, &arg, nullptr, state); + return std::unique_ptr(GfxColorSpace::parse(res, &arg, nullptr, state)); } - return colorSpace; } /** * Look up pattern/gradients from the GfxResource dictionary */ -GfxPattern *PdfParser::lookupPattern(Object *obj, GfxState *state) +std::unique_ptr PdfParser::lookupPattern(Object *obj, GfxState *state) { - if (!obj->isName()) - return nullptr; - return res->lookupPattern(obj->getName(), nullptr, state); + if (!obj->isName()) { + return {}; + } + return std::unique_ptr(res->lookupPattern(obj->getName(), nullptr, state)); } // TODO not good that numArgs is ignored but args[] is used: @@ -990,7 +988,7 @@ void PdfParser::opSetFillGray(Object args[], int /*numArgs*/) GfxColor color; builder->beforeStateChange(state); state->setFillPattern(nullptr); - state->setFillColorSpace(new GfxDeviceGrayColorSpace()); + state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); color.c[0] = dblToCol(args[0].getNum()); state->setFillColor(&color); builder->updateStyle(state); @@ -1002,7 +1000,7 @@ void PdfParser::opSetStrokeGray(Object args[], int /*numArgs*/) GfxColor color; builder->beforeStateChange(state); state->setStrokePattern(nullptr); - state->setStrokeColorSpace(new GfxDeviceGrayColorSpace()); + state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); color.c[0] = dblToCol(args[0].getNum()); state->setStrokeColor(&color); builder->updateStyle(state); @@ -1015,7 +1013,7 @@ void PdfParser::opSetFillCMYKColor(Object args[], int /*numArgs*/) int i; builder->beforeStateChange(state); state->setFillPattern(nullptr); - state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); + state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); for (i = 0; i < 4; ++i) { color.c[i] = dblToCol(args[i].getNum()); } @@ -1029,7 +1027,7 @@ void PdfParser::opSetStrokeCMYKColor(Object args[], int /*numArgs*/) GfxColor color; builder->beforeStateChange(state); state->setStrokePattern(nullptr); - state->setStrokeColorSpace(new GfxDeviceCMYKColorSpace()); + state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); for (int i = 0; i < 4; ++i) { color.c[i] = dblToCol(args[i].getNum()); } @@ -1043,7 +1041,7 @@ void PdfParser::opSetFillRGBColor(Object args[], int /*numArgs*/) GfxColor color; builder->beforeStateChange(state); state->setFillPattern(nullptr); - state->setFillColorSpace(new GfxDeviceRGBColorSpace()); + state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); for (int i = 0; i < 3; ++i) { color.c[i] = dblToCol(args[i].getNum()); } @@ -1056,7 +1054,7 @@ void PdfParser::opSetStrokeRGBColor(Object args[], int /*numArgs*/) { GfxColor color; builder->beforeStateChange(state); state->setStrokePattern(nullptr); - state->setStrokeColorSpace(new GfxDeviceRGBColorSpace()); + state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(std::make_unique())); for (int i = 0; i < 3; ++i) { color.c[i] = dblToCol(args[i].getNum()); } @@ -1068,14 +1066,14 @@ void PdfParser::opSetStrokeRGBColor(Object args[], int /*numArgs*/) { void PdfParser::opSetFillColorSpace(Object args[], int numArgs) { assert(numArgs >= 1); - GfxColorSpace *colorSpace = lookupColorSpaceCopy(args[0]); + auto colorSpace = lookupColorSpaceCopy(args[0]); builder->beforeStateChange(state); state->setFillPattern(nullptr); if (colorSpace) { GfxColor color; - state->setFillColorSpace(colorSpace); colorSpace->getDefaultColor(&color); + state->setFillColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace)); state->setFillColor(&color); builder->updateStyle(state); } else { @@ -1089,14 +1087,14 @@ void PdfParser::opSetStrokeColorSpace(Object args[], int numArgs) assert(numArgs >= 1); builder->beforeStateChange(state); - GfxColorSpace *colorSpace = lookupColorSpaceCopy(args[0]); + auto colorSpace = lookupColorSpaceCopy(args[0]); state->setStrokePattern(nullptr); if (colorSpace) { GfxColor color; - state->setStrokeColorSpace(colorSpace); colorSpace->getDefaultColor(&color); + state->setStrokeColorSpace(_POPPLER_CONSUME_UNIQPTR_ARG(colorSpace)); state->setStrokeColor(&color); builder->updateStyle(state); } else { @@ -1159,7 +1157,7 @@ void PdfParser::opSetFillColorN(Object args[], int numArgs) { builder->updateStyle(state); } if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) { - state->setFillPattern(pattern); + state->setFillPattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern)); builder->updateStyle(state); } @@ -1202,7 +1200,7 @@ void PdfParser::opSetStrokeColorN(Object args[], int numArgs) { builder->updateStyle(state); } if (auto pattern = lookupPattern(&(args[numArgs - 1]), state)) { - state->setStrokePattern(pattern); + state->setStrokePattern(_POPPLER_CONSUME_UNIQPTR_ARG(pattern)); builder->updateStyle(state); } @@ -1579,11 +1577,11 @@ void PdfParser::doShadingPatternFillFallback(GfxShadingPattern *sPat, // TODO not good that numArgs is ignored but args[] is used: void PdfParser::opShFill(Object args[], int /*numArgs*/) { - GfxShading *shading = nullptr; GfxPath *savedPath = nullptr; bool savedState = false; - if (!(shading = res->lookupShading(args[0].getName(), nullptr, state))) { + auto shading = std::unique_ptr(res->lookupShading(args[0].getName(), nullptr, state)); + if (!shading) { return; } @@ -1615,19 +1613,19 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) // do shading type-specific operations switch (shading->getType()) { case 1: // Function-based shading - doFunctionShFill(static_cast(shading)); + doFunctionShFill(static_cast(shading.get())); break; case 2: // Axial shading case 3: // Radial shading - builder->addClippedFill(shading, stateToAffine(state)); + builder->addClippedFill(shading.get(), stateToAffine(state)); break; case 4: // Free-form Gouraud-shaded triangle mesh case 5: // Lattice-form Gouraud-shaded triangle mesh - doGouraudTriangleShFill(static_cast(shading)); + doGouraudTriangleShFill(static_cast(shading.get())); break; case 6: // Coons patch mesh case 7: // Tensor-product patch mesh - doPatchMeshShFill(static_cast(shading)); + doPatchMeshShFill(static_cast(shading.get())); break; } @@ -1636,8 +1634,6 @@ void PdfParser::opShFill(Object args[], int /*numArgs*/) restoreState(); state->setPath(savedPath); } - - delete shading; } void PdfParser::doFunctionShFill(GfxFunctionShading *shading) { @@ -2528,7 +2524,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) } else { // get color space and color map - GfxColorSpace *colorSpace; + std::unique_ptr colorSpace; _POPPLER_CALL_ARGS(obj1, dict->lookup, "ColorSpace"); if (obj1.isNull()) { _POPPLER_FREE(obj1); @@ -2537,13 +2533,11 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) if (!obj1.isNull()) { colorSpace = lookupColorSpaceCopy(obj1); } else if (csMode == streamCSDeviceGray) { - colorSpace = new GfxDeviceGrayColorSpace(); + colorSpace = std::make_unique(); } else if (csMode == streamCSDeviceRGB) { - colorSpace = new GfxDeviceRGBColorSpace(); + colorSpace = std::make_unique(); } else if (csMode == streamCSDeviceCMYK) { - colorSpace = new GfxDeviceCMYKColorSpace(); - } else { - colorSpace = nullptr; + colorSpace = std::make_unique(); } _POPPLER_FREE(obj1); if (!colorSpace) { @@ -2554,10 +2548,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) _POPPLER_FREE(obj1); _POPPLER_CALL_ARGS(obj1, dict->lookup, "D"); } - GfxImageColorMap *colorMap = new GfxImageColorMap(bits, &obj1, colorSpace); + auto colorMap = std::make_unique(bits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(colorSpace)); _POPPLER_FREE(obj1); if (!colorMap->isOk()) { - delete colorMap; goto err1; } @@ -2568,7 +2561,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) int maskWidth = 0; int maskHeight = 0; maskInvert = gFalse; - GfxImageColorMap *maskColorMap = nullptr; + std::unique_ptr maskColorMap; _POPPLER_CALL_ARGS(maskObj, dict->lookup, "Mask"); _POPPLER_CALL_ARGS(smaskObj, dict->lookup, "SMask"); Dict* maskDict; @@ -2624,7 +2617,7 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) _POPPLER_FREE(obj1); _POPPLER_CALL_ARGS(obj1, maskDict->lookup, "CS"); } - GfxColorSpace *maskColorSpace = lookupColorSpaceCopy(obj1); + auto maskColorSpace = lookupColorSpaceCopy(obj1); _POPPLER_FREE(obj1); if (!maskColorSpace || maskColorSpace->getMode() != csDeviceGray) { goto err1; @@ -2634,10 +2627,9 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) _POPPLER_FREE(obj1); _POPPLER_CALL_ARGS(obj1, maskDict->lookup, "D"); } - maskColorMap = new GfxImageColorMap(maskBits, &obj1, maskColorSpace); + maskColorMap = std::make_unique(maskBits, &obj1, _POPPLER_CONSUME_UNIQPTR_ARG(maskColorSpace)); _POPPLER_FREE(obj1); if (!maskColorMap->isOk()) { - delete maskColorMap; goto err1; } //~ handle the Matte entry @@ -2718,17 +2710,15 @@ void PdfParser::doImage(Object * /*ref*/, Stream *str, GBool inlineImg) // draw it if (haveSoftMask) { - builder->addSoftMaskedImage(state, str, width, height, colorMap, interpolate, - maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate); - delete maskColorMap; + builder->addSoftMaskedImage(state, str, width, height, colorMap.get(), interpolate, + maskStr, maskWidth, maskHeight, maskColorMap.get(), maskInterpolate); } else if (haveExplicitMask) { - builder->addMaskedImage(state, str, width, height, colorMap, interpolate, + builder->addMaskedImage(state, str, width, height, colorMap.get(), interpolate, maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate); } else { - builder->addImage(state, str, width, height, colorMap, interpolate, - haveColorKeyMask ? maskColors : static_cast(nullptr)); + builder->addImage(state, str, width, height, colorMap.get(), interpolate, + haveColorKeyMask ? maskColors : nullptr); } - delete colorMap; _POPPLER_FREE(maskObj); _POPPLER_FREE(smaskObj); @@ -2746,7 +2736,6 @@ void PdfParser::doForm(Object *str, double *offset) { Dict *dict; GBool transpGroup, isolated, knockout; - GfxColorSpace *blendingColorSpace; Object matrixObj, bboxObj; double m[6], bbox[4]; Object resObj; @@ -2812,12 +2801,12 @@ void PdfParser::doForm(Object *str, double *offset) // check for a transparency group transpGroup = isolated = knockout = gFalse; - blendingColorSpace = nullptr; + std::unique_ptr blendingColorSpace; if (_POPPLER_CALL_ARGS_DEREF(obj1, dict->lookup, "Group").isDict()) { if (_POPPLER_CALL_ARGS_DEREF(obj2, obj1.dictLookup, "S").isName("Transparency")) { transpGroup = gTrue; if (!_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup, "CS").isNull()) { - blendingColorSpace = GfxColorSpace::parse(nullptr, &obj3, nullptr, state); + blendingColorSpace = std::unique_ptr(GfxColorSpace::parse(nullptr, &obj3, nullptr, state)); } _POPPLER_FREE(obj3); if (_POPPLER_CALL_ARGS_DEREF(obj3, obj1.dictLookup, "I").isBool()) { @@ -2835,12 +2824,9 @@ void PdfParser::doForm(Object *str, double *offset) // draw it ++formDepth; - doForm1(str, resDict, m, bbox, transpGroup, gFalse, blendingColorSpace, isolated, knockout); + doForm1(str, resDict, m, bbox, transpGroup, gFalse, blendingColorSpace.get(), isolated, knockout); --formDepth; - if (blendingColorSpace) { - delete blendingColorSpace; - } _POPPLER_FREE(resObj); } diff --git a/src/extension/internal/pdfinput/pdf-parser.h b/src/extension/internal/pdfinput/pdf-parser.h index c7c10caefed..8325ea24364 100644 --- a/src/extension/internal/pdfinput/pdf-parser.h +++ b/src/extension/internal/pdfinput/pdf-parser.h @@ -137,7 +137,7 @@ public: void loadPatternColorProfiles(Dict *resources); void loadColorProfile(); void loadColorSpaceProfile(GfxColorSpace *space, Object *obj); - GfxPattern *lookupPattern(Object *obj, GfxState *state); + std::unique_ptr lookupPattern(Object *obj, GfxState *state); std::shared_ptr getFontEngine(); @@ -176,7 +176,7 @@ private: //! Caches color spaces by name std::map> colorSpacesCache; - GfxColorSpace *lookupColorSpaceCopy(Object &); + std::unique_ptr lookupColorSpaceCopy(Object &); void setDefaultApproximationPrecision(); // init color deltas void pushOperator(const char *name); diff --git a/src/extension/internal/pdfinput/poppler-transition-api.h b/src/extension/internal/pdfinput/poppler-transition-api.h index 481aefadf46..8f03aa17779 100644 --- a/src/extension/internal/pdfinput/poppler-transition-api.h +++ b/src/extension/internal/pdfinput/poppler-transition-api.h @@ -15,6 +15,12 @@ #include #include +#if POPPLER_CHECK_VERSION(24, 10, 0) +#define _POPPLER_CONSUME_UNIQPTR_ARG(value) std::move(value) +#else +#define _POPPLER_CONSUME_UNIQPTR_ARG(value) value.release() +#endif + #if POPPLER_CHECK_VERSION(24, 5, 0) #define _POPPLER_HAS_UNICODE_BOM(value) (hasUnicodeByteOrderMark(value->toStr())) #define _POPPLER_HAS_UNICODE_BOMLE(value) (hasUnicodeByteOrderMarkLE(value->toStr())) -- GitLab