Avoid integer overflows in FXGE_GetGlyphsBBox().

And also CFX_RenderDevice::DrawNormalText().

BUG=637192

Review-Url: https://codereview.chromium.org/2244613002
diff --git a/core/fxge/ge/cfx_renderdevice.cpp b/core/fxge/ge/cfx_renderdevice.cpp
index 53ee039..fcb99f7 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 @@
   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 @@
     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 ac110b0..5fea141 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 @@
     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;
 }