summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2017-03-01 00:32:20 -0800
committerChromium commit bot <commit-bot@chromium.org>2017-03-01 16:45:36 +0000
commitef81390393ef5fed1ba168cff081d459eed9f260 (patch)
tree89dcc109865b846a95a3f6e121d900e9a03b240d
parente13ad88925bde037f4ed3b60f9ea5f01b883aa6e (diff)
downloadpdfium-ef81390393ef5fed1ba168cff081d459eed9f260.tar.xz
Fix infinite loops in CPDF_MeshStream.
BUG=chromium:690501 Change-Id: I74b09d90a8082554a67f737eb6adc3bff82ed93e Reviewed-on: https://pdfium-review.googlesource.com/2889 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: dsinclair <dsinclair@chromium.org>
-rw-r--r--core/fpdfapi/page/cpdf_meshstream.cpp37
-rw-r--r--core/fpdfapi/page/cpdf_meshstream.h8
-rw-r--r--core/fpdfapi/page/cpdf_streamcontentparser.cpp7
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.cpp18
4 files changed, 57 insertions, 13 deletions
diff --git a/core/fpdfapi/page/cpdf_meshstream.cpp b/core/fpdfapi/page/cpdf_meshstream.cpp
index 75069cab7f..24ef9b271e 100644
--- a/core/fpdfapi/page/cpdf_meshstream.cpp
+++ b/core/fpdfapi/page/cpdf_meshstream.cpp
@@ -154,6 +154,18 @@ bool CPDF_MeshStream::Load() {
return true;
}
+bool CPDF_MeshStream::CanReadFlag() const {
+ return m_BitStream.BitsRemaining() >= m_nFlagBits;
+}
+
+bool CPDF_MeshStream::CanReadCoords() const {
+ return m_BitStream.BitsRemaining() / 2 >= m_nCoordBits;
+}
+
+bool CPDF_MeshStream::CanReadColor() const {
+ return m_BitStream.BitsRemaining() / m_nComponentBits >= m_nComponents;
+}
+
uint32_t CPDF_MeshStream::ReadFlag() {
ASSERT(ShouldCheckBitsPerFlag(m_type));
return m_BitStream.GetBits(m_nFlagBits) & 0x03;
@@ -209,26 +221,35 @@ std::tuple<FX_FLOAT, FX_FLOAT, FX_FLOAT> CPDF_MeshStream::ReadColor() {
return std::tuple<FX_FLOAT, FX_FLOAT, FX_FLOAT>(r, g, b);
}
-CPDF_MeshVertex CPDF_MeshStream::ReadVertex(const CFX_Matrix& pObject2Bitmap,
- uint32_t* flag) {
+bool CPDF_MeshStream::ReadVertex(const CFX_Matrix& pObject2Bitmap,
+ CPDF_MeshVertex* vertex,
+ uint32_t* flag) {
+ if (!CanReadFlag())
+ return false;
*flag = ReadFlag();
- CPDF_MeshVertex vertex;
- vertex.position = pObject2Bitmap.Transform(ReadCoords());
- std::tie(vertex.r, vertex.g, vertex.b) = ReadColor();
- m_BitStream.ByteAlign();
+ if (!CanReadCoords())
+ return false;
+ vertex->position = pObject2Bitmap.Transform(ReadCoords());
- return vertex;
+ if (!CanReadColor())
+ return false;
+ std::tie(vertex->r, vertex->g, vertex->b) = ReadColor();
+ m_BitStream.ByteAlign();
+ return true;
}
bool CPDF_MeshStream::ReadVertexRow(const CFX_Matrix& pObject2Bitmap,
int count,
CPDF_MeshVertex* vertex) {
for (int i = 0; i < count; i++) {
- if (m_BitStream.IsEOF())
+ if (m_BitStream.IsEOF() || !CanReadCoords())
return false;
vertex[i].position = pObject2Bitmap.Transform(ReadCoords());
+ if (!CanReadColor())
+ return false;
+
std::tie(vertex[i].r, vertex[i].g, vertex[i].b) = ReadColor();
m_BitStream.ByteAlign();
}
diff --git a/core/fpdfapi/page/cpdf_meshstream.h b/core/fpdfapi/page/cpdf_meshstream.h
index 24f1d66cfd..d40de4a013 100644
--- a/core/fpdfapi/page/cpdf_meshstream.h
+++ b/core/fpdfapi/page/cpdf_meshstream.h
@@ -42,11 +42,17 @@ class CPDF_MeshStream {
bool Load();
+ bool CanReadFlag() const;
+ bool CanReadCoords() const;
+ bool CanReadColor() const;
+
uint32_t ReadFlag();
CFX_PointF ReadCoords();
std::tuple<FX_FLOAT, FX_FLOAT, FX_FLOAT> ReadColor();
- CPDF_MeshVertex ReadVertex(const CFX_Matrix& pObject2Bitmap, uint32_t* flag);
+ bool ReadVertex(const CFX_Matrix& pObject2Bitmap,
+ CPDF_MeshVertex* vertex,
+ uint32_t* flag);
bool ReadVertexRow(const CFX_Matrix& pObject2Bitmap,
int count,
CPDF_MeshVertex* vertex);
diff --git a/core/fpdfapi/page/cpdf_streamcontentparser.cpp b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
index d8e1c1e15d..6211b6a4dd 100644
--- a/core/fpdfapi/page/cpdf_streamcontentparser.cpp
+++ b/core/fpdfapi/page/cpdf_streamcontentparser.cpp
@@ -98,8 +98,11 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading,
while (!stream.BitStream()->IsEOF()) {
uint32_t flag = 0;
- if (type != kLatticeFormGouraudTriangleMeshShading)
+ if (type != kLatticeFormGouraudTriangleMeshShading) {
+ if (!stream.CanReadFlag())
+ break;
flag = stream.ReadFlag();
+ }
if (!bGouraud && flag) {
point_count -= 4;
@@ -107,6 +110,8 @@ CFX_FloatRect GetShadingBBox(CPDF_ShadingPattern* pShading,
}
for (int i = 0; i < point_count; i++) {
+ if (!stream.CanReadCoords())
+ break;
CFX_PointF origin = stream.ReadCoords();
if (bStarted) {
rect.UpdateRect(origin.x, origin.y);
diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp
index 1e67eaba55..9022212ecc 100644
--- a/core/fpdfapi/render/cpdf_renderstatus.cpp
+++ b/core/fpdfapi/render/cpdf_renderstatus.cpp
@@ -487,13 +487,17 @@ void DrawFreeGouraudShading(
FXSYS_memset(triangle, 0, sizeof(triangle));
while (!stream.BitStream()->IsEOF()) {
+ CPDF_MeshVertex vertex;
uint32_t flag;
- CPDF_MeshVertex vertex = stream.ReadVertex(*pObject2Bitmap, &flag);
+ if (!stream.ReadVertex(*pObject2Bitmap, &vertex, &flag))
+ return;
+
if (flag == 0) {
triangle[0] = vertex;
for (int j = 1; j < 3; j++) {
uint32_t tflag;
- triangle[j] = stream.ReadVertex(*pObject2Bitmap, &tflag);
+ if (!stream.ReadVertex(*pObject2Bitmap, &triangle[j], &tflag))
+ return;
}
} else {
if (flag == 1)
@@ -831,6 +835,8 @@ void DrawCoonPatchMeshes(
CFX_PointF coords[16];
int point_count = type == kTensorProductPatchMeshShading ? 16 : 12;
while (!stream.BitStream()->IsEOF()) {
+ if (!stream.CanReadFlag())
+ break;
uint32_t flag = stream.ReadFlag();
int iStartPoint = 0, iStartColor = 0, i = 0;
if (flag) {
@@ -846,10 +852,16 @@ void DrawCoonPatchMeshes(
tempColors[1] = patch.patch_colors[(flag + 1) % 4];
FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2);
}
- for (i = iStartPoint; i < point_count; i++)
+ for (i = iStartPoint; i < point_count; i++) {
+ if (!stream.CanReadCoords())
+ break;
coords[i] = pObject2Bitmap->Transform(stream.ReadCoords());
+ }
for (i = iStartColor; i < 4; i++) {
+ if (!stream.CanReadColor())
+ break;
+
FX_FLOAT r;
FX_FLOAT g;
FX_FLOAT b;