summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthestig <thestig@chromium.org>2016-08-15 14:33:21 -0700
committerCommit bot <commit-bot@chromium.org>2016-08-15 14:33:22 -0700
commit19cdfe4d73370b21709aefd9dce06cf463239fa1 (patch)
tree4f1c00074c2f5c04fd32a90e125d56d3ebe464ba
parentef523dd36aea991084b8b934df846014a5c09c6f (diff)
downloadpdfium-19cdfe4d73370b21709aefd9dce06cf463239fa1.tar.xz
Avoid integer overflows in FXGE_GetGlyphsBBox().
And also CFX_RenderDevice::DrawNormalText(). BUG=637192 Review-Url: https://codereview.chromium.org/2244613002
-rw-r--r--core/fxge/ge/cfx_renderdevice.cpp37
-rw-r--r--core/fxge/ge/fx_ge_text.cpp61
2 files changed, 71 insertions, 27 deletions
diff --git a/core/fxge/ge/cfx_renderdevice.cpp b/core/fxge/ge/cfx_renderdevice.cpp
index 53ee039cd3..fcb99f79c2 100644
--- a/core/fxge/ge/cfx_renderdevice.cpp
+++ b/core/fxge/ge/cfx_renderdevice.cpp
@@ -6,6 +6,7 @@
#include "core/fxge/include/cfx_renderdevice.h"
+#include "core/fxcrt/include/fx_safe_types.h"
#include "core/fxge/include/cfx_fxgedevice.h"
#include "core/fxge/include/cfx_graphstatedata.h"
#include "core/fxge/include/cfx_pathdata.h"
@@ -997,17 +998,30 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
int b = 0;
if (anti_alias == FXFT_RENDER_MODE_LCD)
ArgbDecode(fill_color, a, r, g, b);
+
for (const FXTEXT_GLYPHPOS& glyph : glyphs) {
if (!glyph.m_pGlyph)
continue;
+
+ pdfium::base::CheckedNumeric<int> left = glyph.m_OriginX;
+ left += glyph.m_pGlyph->m_Left;
+ left -= pixel_left;
+ if (!left.IsValid())
+ return FALSE;
+
+ pdfium::base::CheckedNumeric<int> top = glyph.m_OriginY;
+ top -= glyph.m_pGlyph->m_Top;
+ top -= pixel_top;
+ if (!top.IsValid())
+ return FALSE;
+
const CFX_DIBitmap* pGlyph = &glyph.m_pGlyph->m_Bitmap;
- int left = glyph.m_OriginX + glyph.m_pGlyph->m_Left - pixel_left;
- int top = glyph.m_OriginY - glyph.m_pGlyph->m_Top - pixel_top;
int ncols = pGlyph->GetWidth();
int nrows = pGlyph->GetHeight();
if (anti_alias == FXFT_RENDER_MODE_NORMAL) {
- if (!bitmap.CompositeMask(left, top, ncols, nrows, pGlyph, fill_color, 0,
- 0, FXDIB_BLEND_NORMAL, nullptr, FALSE, 0,
+ if (!bitmap.CompositeMask(left.ValueOrDie(), top.ValueOrDie(), ncols,
+ nrows, pGlyph, fill_color, 0, 0,
+ FXDIB_BLEND_NORMAL, nullptr, FALSE, 0,
nullptr)) {
return FALSE;
}
@@ -1016,12 +1030,19 @@ FX_BOOL CFX_RenderDevice::DrawNormalText(int nChars,
bool bBGRStripe = !!(text_flags & FXTEXT_BGR_STRIPE);
ncols /= 3;
int x_subpixel = (int)(glyph.m_fOriginX * 3) % 3;
- int start_col = std::max(left, 0);
- int end_col = std::min(left + ncols, dest_width);
+ int start_col = std::max(left.ValueOrDie(), 0);
+ pdfium::base::CheckedNumeric<int> end_col_safe = left;
+ end_col_safe += ncols;
+ if (!end_col_safe.IsValid())
+ return FALSE;
+
+ int end_col = std::min(end_col_safe.ValueOrDie(), dest_width);
if (start_col >= end_col)
continue;
- DrawNormalTextHelper(&bitmap, pGlyph, nrows, left, top, start_col, end_col,
- bNormal, bBGRStripe, x_subpixel, a, r, g, b);
+
+ DrawNormalTextHelper(&bitmap, pGlyph, nrows, left.ValueOrDie(),
+ top.ValueOrDie(), start_col, end_col, bNormal,
+ bBGRStripe, x_subpixel, a, r, g, b);
}
if (bitmap.IsAlphaMask())
SetBitMask(&bitmap, bmp_rect.left, bmp_rect.top, fill_color);
diff --git a/core/fxge/ge/fx_ge_text.cpp b/core/fxge/ge/fx_ge_text.cpp
index ac110b0291..5fea141a42 100644
--- a/core/fxge/ge/fx_ge_text.cpp
+++ b/core/fxge/ge/fx_ge_text.cpp
@@ -8,6 +8,7 @@
#include <vector>
#include "core/fxcodec/include/fx_codec.h"
+#include "core/fxcrt/include/fx_safe_types.h"
#include "core/fxge/ge/fx_text_int.h"
#include "core/fxge/include/cfx_fontmgr.h"
#include "core/fxge/include/cfx_gemodule.h"
@@ -58,27 +59,49 @@ FX_RECT FXGE_GetGlyphsBBox(const std::vector<FXTEXT_GLYPHPOS>& glyphs,
if (!pGlyph)
continue;
- int char_left = glyph.m_OriginX + pGlyph->m_Left;
- int char_width = (int)(pGlyph->m_Bitmap.GetWidth() / retinaScaleX);
- if (anti_alias == FXFT_RENDER_MODE_LCD) {
+ FX_SAFE_INT32 char_left = glyph.m_OriginX;
+ char_left += pGlyph->m_Left;
+ if (!char_left.IsValid())
+ continue;
+
+ FX_SAFE_INT32 char_width = pGlyph->m_Bitmap.GetWidth();
+ char_width /= retinaScaleX;
+ if (anti_alias == FXFT_RENDER_MODE_LCD)
char_width /= 3;
+ if (!char_width.IsValid())
+ continue;
+
+ FX_SAFE_INT32 char_right = char_left + char_width;
+ if (!char_right.IsValid())
+ continue;
+
+ FX_SAFE_INT32 char_top = glyph.m_OriginY;
+ char_top -= pGlyph->m_Top;
+ if (!char_top.IsValid())
+ continue;
+
+ FX_SAFE_INT32 char_height = pGlyph->m_Bitmap.GetHeight();
+ char_height /= retinaScaleY;
+ if (!char_height.IsValid())
+ continue;
+
+ FX_SAFE_INT32 char_bottom = char_top + char_height;
+ if (!char_bottom.IsValid())
+ continue;
+
+ if (bStarted) {
+ rect.left = std::min(rect.left, char_left.ValueOrDie());
+ rect.right = std::max(rect.right, char_right.ValueOrDie());
+ rect.top = std::min(rect.top, char_top.ValueOrDie());
+ rect.bottom = std::max(rect.bottom, char_bottom.ValueOrDie());
+ continue;
}
- int char_right = char_left + char_width;
- int char_top = glyph.m_OriginY - pGlyph->m_Top;
- int char_bottom =
- char_top + (int)(pGlyph->m_Bitmap.GetHeight() / retinaScaleY);
- if (!bStarted) {
- rect.left = char_left;
- rect.right = char_right;
- rect.top = char_top;
- rect.bottom = char_bottom;
- bStarted = true;
- } else {
- rect.left = std::min(rect.left, char_left);
- rect.right = std::max(rect.right, char_right);
- rect.top = std::min(rect.top, char_top);
- rect.bottom = std::max(rect.bottom, char_bottom);
- }
+
+ rect.left = char_left.ValueOrDie();
+ rect.right = char_right.ValueOrDie();
+ rect.top = char_top.ValueOrDie();
+ rect.bottom = char_bottom.ValueOrDie();
+ bStarted = true;
}
return rect;
}