[poppler] poppler/GfxState.cc poppler/GfxState.h
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Fri Feb 12 23:31:25 UTC 2021
poppler/GfxState.cc | 191 ++++++++++++++++++++++++++++++++++++++++++++--------
poppler/GfxState.h | 16 +++-
2 files changed, 176 insertions(+), 31 deletions(-)
New commits:
commit 2e62feafbc5095cedf948aefdf771d328d978de9
Author: Albert Astals Cid <aacid at kde.org>
Date: Fri Feb 12 14:16:09 2021 +0100
Improve well formed check for shading functions
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index a67c7ff7..05ce3a8e 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -3663,6 +3663,45 @@ GfxFunctionShading *GfxFunctionShading::parse(GfxResources *res, Dict *dict, Out
return shading;
}
+bool GfxFunctionShading::init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
+{
+ const bool parentInit = GfxShading::init(res, dict, out, state);
+ if (!parentInit) {
+ return false;
+ }
+
+ // funcs needs to be one of the two:
+ // * One function 2-in -> nComps-out
+ // * nComps functions 2-in -> 1-out
+ const int nComps = colorSpace->getNComps();
+ const int nFuncs = funcs.size();
+ if (nFuncs == 1) {
+ if (funcs[0]->getInputSize() != 2) {
+ error(errSyntaxWarning, -1, "GfxFunctionShading: function with input size != 2");
+ return false;
+ }
+ if (funcs[0]->getOutputSize() != nComps) {
+ error(errSyntaxWarning, -1, "GfxFunctionShading: function with wrong output size");
+ return false;
+ }
+ } else if (nFuncs == nComps) {
+ for (const std::unique_ptr<Function> &f : funcs) {
+ if (f->getInputSize() != 2) {
+ error(errSyntaxWarning, -1, "GfxFunctionShading: function with input size != 2");
+ return false;
+ }
+ if (f->getOutputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxFunctionShading: function with wrong output size");
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
GfxShading *GfxFunctionShading::copy() const
{
return new GfxFunctionShading(this);
@@ -3680,11 +3719,7 @@ void GfxFunctionShading::getColor(double x, double y, GfxColor *color) const
in[0] = x;
in[1] = y;
for (int i = 0; i < getNFuncs(); ++i) {
- if (likely(funcs[i]->getInputSize() <= 2)) {
- funcs[i]->transform(in, &out[i]);
- } else {
- error(errSyntaxWarning, -1, "GfxFunctionShading::getColor: function with input size > 2");
- }
+ funcs[i]->transform(in, &out[i]);
}
for (int i = 0; i < gfxColorMaxComps; ++i) {
color->c[i] = dblToCol(out[i]);
@@ -3734,18 +3769,10 @@ GfxUnivariateShading::~GfxUnivariateShading()
int GfxUnivariateShading::getColor(double t, GfxColor *color)
{
double out[gfxColorMaxComps];
- int nComps;
-
- if (likely(getNFuncs() >= 1)) {
- // NB: there can be one function with n outputs or n functions with
- // one output each (where n = number of color components)
- nComps = getNFuncs() * funcs[0]->getOutputSize();
- }
- if (unlikely(getNFuncs() < 1 || nComps > gfxColorMaxComps)) {
- clearGfxColor(color);
- return gfxColorMaxComps;
- }
+ // NB: there can be one function with n outputs or n functions with
+ // one output each (where n = number of color components)
+ const int nComps = getNFuncs() * funcs[0]->getOutputSize();
if (cacheSize > 0) {
double x, ix, *l, *u, *upper;
@@ -3773,10 +3800,6 @@ int GfxUnivariateShading::getColor(double t, GfxColor *color)
out[i] = 0;
}
for (int i = 0; i < getNFuncs(); ++i) {
- if (funcs[i]->getInputSize() != 1) {
- error(errSyntaxWarning, -1, "Invalid shading function (input != 1)");
- break;
- }
funcs[i]->transform(&t, &out[i]);
}
}
@@ -3870,6 +3893,45 @@ void GfxUnivariateShading::setupCache(const Matrix *ctm, double xMin, double yMi
lastMatch = 1;
}
+bool GfxUnivariateShading::init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
+{
+ const bool parentInit = GfxShading::init(res, dict, out, state);
+ if (!parentInit) {
+ return false;
+ }
+
+ // funcs needs to be one of the two:
+ // * One function 1-in -> nComps-out
+ // * nComps functions 1-in -> 1-out
+ const int nComps = colorSpace->getNComps();
+ const int nFuncs = funcs.size();
+ if (nFuncs == 1) {
+ if (funcs[0]->getInputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxUnivariateShading: function with input size != 2");
+ return false;
+ }
+ if (funcs[0]->getOutputSize() != nComps) {
+ error(errSyntaxWarning, -1, "GfxUnivariateShading: function with wrong output size");
+ return false;
+ }
+ } else if (nFuncs == nComps) {
+ for (const std::unique_ptr<Function> &f : funcs) {
+ if (f->getInputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxUnivariateShading: function with input size != 2");
+ return false;
+ }
+ if (f->getOutputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxUnivariateShading: function with wrong output size");
+ return false;
+ }
+ }
+ } else {
+ return false;
+ }
+
+ return true;
+}
+
//------------------------------------------------------------------------
// GfxAxialShading
//------------------------------------------------------------------------
@@ -4762,6 +4824,46 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, i
return shading;
}
+bool GfxGouraudTriangleShading::init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
+{
+ const bool parentInit = GfxShading::init(res, dict, out, state);
+ if (!parentInit) {
+ return false;
+ }
+
+ // funcs needs to be one of the three:
+ // * One function 1-in -> nComps-out
+ // * nComps functions 1-in -> 1-out
+ // * empty
+ const int nComps = colorSpace->getNComps();
+ const int nFuncs = funcs.size();
+ if (nFuncs == 1) {
+ if (funcs[0]->getInputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxGouraudTriangleShading: function with input size != 2");
+ return false;
+ }
+ if (funcs[0]->getOutputSize() != nComps) {
+ error(errSyntaxWarning, -1, "GfxGouraudTriangleShading: function with wrong output size");
+ return false;
+ }
+ } else if (nFuncs == nComps) {
+ for (const std::unique_ptr<Function> &f : funcs) {
+ if (f->getInputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxGouraudTriangleShading: function with input size != 2");
+ return false;
+ }
+ if (f->getOutputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxGouraudTriangleShading: function with wrong output size");
+ return false;
+ }
+ }
+ } else if (nFuncs != 0) {
+ return false;
+ }
+
+ return true;
+}
+
GfxShading *GfxGouraudTriangleShading::copy() const
{
return new GfxGouraudTriangleShading(this);
@@ -4948,15 +5050,6 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di
}
}
- for (unsigned int k = 0; k < funcsA.size(); ++k) {
- if (funcsA[k]->getInputSize() > 1) {
- return nullptr;
- }
- if (funcsA[k]->getOutputSize() > static_cast<int>(gfxColorMaxComps - k)) {
- return nullptr;
- }
- }
-
nPatchesA = 0;
patchesA = nullptr;
patchesSize = 0;
@@ -5378,6 +5471,46 @@ GfxPatchMeshShading *GfxPatchMeshShading::parse(GfxResources *res, int typeA, Di
return shading;
}
+bool GfxPatchMeshShading::init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state)
+{
+ const bool parentInit = GfxShading::init(res, dict, out, state);
+ if (!parentInit) {
+ return false;
+ }
+
+ // funcs needs to be one of the three:
+ // * One function 1-in -> nComps-out
+ // * nComps functions 1-in -> 1-out
+ // * empty
+ const int nComps = colorSpace->getNComps();
+ const int nFuncs = funcs.size();
+ if (nFuncs == 1) {
+ if (funcs[0]->getInputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxPatchMeshShading: function with input size != 2");
+ return false;
+ }
+ if (funcs[0]->getOutputSize() != nComps) {
+ error(errSyntaxWarning, -1, "GfxPatchMeshShading: function with wrong output size");
+ return false;
+ }
+ } else if (nFuncs == nComps) {
+ for (const std::unique_ptr<Function> &f : funcs) {
+ if (f->getInputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxPatchMeshShading: function with input size != 2");
+ return false;
+ }
+ if (f->getOutputSize() != 1) {
+ error(errSyntaxWarning, -1, "GfxPatchMeshShading: function with wrong output size");
+ return false;
+ }
+ }
+ } else if (nFuncs != 0) {
+ return false;
+ }
+
+ return true;
+}
+
void GfxPatchMeshShading::getParameterizedColor(double t, GfxColor *color) const
{
double out[gfxColorMaxComps] = {};
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 10953b0b..aec5c6c8 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -17,7 +17,7 @@
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff at infidigm.net>
// Copyright (C) 2006 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2009 Koji Otani <sho at bbr.jp>
-// Copyright (C) 2009-2011, 2013, 2016-2020 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2009-2011, 2013, 2016-2021 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2010 Christian Feuersänger <cfeuersaenger at googlemail.com>
// Copyright (C) 2011 Andrea Canciani <ranma42 at gmail.com>
// Copyright (C) 2011-2014, 2016, 2020 Thomas Freitag <Thomas.Freitag at alfa.de>
@@ -878,7 +878,7 @@ public:
bool getHasBBox() const { return hasBBox; }
protected:
- bool init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
+ virtual bool init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state);
// 1: Function-based shading
// 2: Axial shading
@@ -922,6 +922,9 @@ public:
virtual double getDistance(double sMin, double sMax) const = 0;
+protected:
+ bool init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) override;
+
private:
double t0, t1;
std::vector<std::unique_ptr<Function>> funcs;
@@ -960,6 +963,9 @@ public:
const Function *getFunc(int i) const { return funcs[i].get(); }
void getColor(double x, double y, GfxColor *color) const;
+protected:
+ bool init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) override;
+
private:
double x0, y0, x1, y1;
double matrix[6];
@@ -1087,6 +1093,9 @@ public:
void getParameterizedColor(double t, GfxColor *color) const;
+protected:
+ bool init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) override;
+
private:
GfxGouraudVertex *vertices;
int nVertices;
@@ -1165,6 +1174,9 @@ public:
void getParameterizedColor(double t, GfxColor *color) const;
+protected:
+ bool init(GfxResources *res, Dict *dict, OutputDev *out, GfxState *state) override;
+
private:
GfxPatch *patches;
int nPatches;
More information about the poppler
mailing list