Consistently use FXSYS_IsDecimalDigit()

Replace first-party isdigit() calls with FXSYS_IsDecimalDigit(). This
avoids potentially unexpected behavior if the char type is signed, since
isdigit() actually expects the input to be an unsigned char.

Change-Id: I05f0b99aad8740b5dcae24df153e23ec4dd999bc
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/126052
Commit-Queue: Lei Zhang <thestig@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Thomas Sepez <tsepez@google.com>
diff --git a/core/fpdfapi/font/cpdf_cmapparser.cpp b/core/fpdfapi/font/cpdf_cmapparser.cpp
index 1a5874f..01f3d69 100644
--- a/core/fpdfapi/font/cpdf_cmapparser.cpp
+++ b/core/fpdfapi/font/cpdf_cmapparser.cpp
@@ -153,8 +153,9 @@
     return num.ValueOrDie();
   }
 
-  for (size_t i = 0; i < word.GetLength() && isdigit(word[i]); ++i) {
-    num = num * 10 + FXSYS_DecimalCharToInt(static_cast<wchar_t>(word[i]));
+  for (size_t i = 0;
+       i < word.GetLength() && FXSYS_IsDecimalDigit(word.CharAt(i)); ++i) {
+    num = num * 10 + FXSYS_DecimalCharToInt(word.CharAt(i));
     if (!num.IsValid())
       return 0;
   }
diff --git a/core/fpdfapi/parser/cpdf_parser.cpp b/core/fpdfapi/parser/cpdf_parser.cpp
index 7fdd089..3e8a13a 100644
--- a/core/fpdfapi/parser/cpdf_parser.cpp
+++ b/core/fpdfapi/parser/cpdf_parser.cpp
@@ -6,7 +6,6 @@
 
 #include "core/fpdfapi/parser/cpdf_parser.h"
 
-#include <ctype.h>
 #include <stdint.h>
 
 #include <algorithm>
@@ -205,17 +204,23 @@
 bool CPDF_Parser::ParseFileVersion() {
   m_FileVersion = 0;
   uint8_t ch;
-  if (!m_pSyntax->GetCharAt(5, ch))
+  if (!m_pSyntax->GetCharAt(5, ch)) {
     return false;
+  }
 
-  if (isdigit(ch))
-    m_FileVersion = FXSYS_DecimalCharToInt(static_cast<wchar_t>(ch)) * 10;
+  wchar_t wch = static_cast<wchar_t>(ch);
+  if (FXSYS_IsDecimalDigit(wch)) {
+    m_FileVersion = FXSYS_DecimalCharToInt(wch) * 10;
+  }
 
-  if (!m_pSyntax->GetCharAt(7, ch))
+  if (!m_pSyntax->GetCharAt(7, ch)) {
     return false;
+  }
 
-  if (isdigit(ch))
-    m_FileVersion += FXSYS_DecimalCharToInt(static_cast<wchar_t>(ch));
+  wch = static_cast<wchar_t>(ch);
+  if (FXSYS_IsDecimalDigit(wch)) {
+    m_FileVersion += FXSYS_DecimalCharToInt(wch);
+  }
   return true;
 }
 
@@ -559,8 +564,9 @@
 
         if (offset.ValueOrDie() == 0) {
           for (int32_t c = 0; c < 10; c++) {
-            if (!isdigit(pEntry[c]))
+            if (!FXSYS_IsDecimalDigit(pEntry[c])) {
               return false;
+            }
           }
         }
 
diff --git a/core/fxcrt/fx_number.cpp b/core/fxcrt/fx_number.cpp
index bca64cc..1b87f97 100644
--- a/core/fxcrt/fx_number.cpp
+++ b/core/fxcrt/fx_number.cpp
@@ -6,8 +6,6 @@
 
 #include "core/fxcrt/fx_number.h"
 
-#include <ctype.h>
-
 #include <limits>
 
 #include "core/fxcrt/fx_extension.h"
@@ -48,11 +46,11 @@
     cc++;
   }
 
-  for (; cc < strc.GetLength() && isdigit(strc[cc]); ++cc) {
+  for (; cc < strc.GetLength() && FXSYS_IsDecimalDigit(strc.CharAt(cc)); ++cc) {
     // Deliberately not using FXSYS_DecimalCharToInt() in a tight loop to avoid
-    // a duplicate isdigit() call. Note that the order of operation is
-    // important to avoid unintentional overflows.
-    unsigned_val = unsigned_val * 10 + (strc[cc] - '0');
+    // a duplicate FXSYS_IsDecimalDigit() call. Note that the order of operation
+    // is important to avoid unintentional overflows.
+    unsigned_val = unsigned_val * 10 + (strc.CharAt(cc) - '0');
   }
 
   uint32_t uValue = unsigned_val.ValueOrDefault(0);
diff --git a/fxbarcode/oned/BC_OnedCode128Writer.cpp b/fxbarcode/oned/BC_OnedCode128Writer.cpp
index b21f0f9..a32ef6d 100644
--- a/fxbarcode/oned/BC_OnedCode128Writer.cpp
+++ b/fxbarcode/oned/BC_OnedCode128Writer.cpp
@@ -22,12 +22,11 @@
 
 #include "fxbarcode/oned/BC_OnedCode128Writer.h"
 
-#include <ctype.h>
-
 #include <array>
 #include <memory>
 
 #include "core/fxcrt/check.h"
+#include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_string.h"
 #include "fxbarcode/BC_Writer.h"
 #include "fxbarcode/oned/BC_OneDimWriter.h"
@@ -173,12 +172,13 @@
   const ByteStringView view = contents.AsStringView();
   while (position < view.GetLength()) {
     int32_t patternIndex;
-    char ch = view[position];
-    if (isdigit(ch)) {
+    char ch = view.CharAt(position);
+    if (FXSYS_IsDecimalDigit(ch)) {
       patternIndex = StringToInt(
           view.Substr(position, view.IsValidIndex(position + 1) ? 2 : 1));
       ++position;
-      if (position < view.GetLength() && isdigit(view[position])) {
+      if (position < view.GetLength() &&
+          FXSYS_IsDecimalDigit(view.CharAt(position))) {
         ++position;
       }
     } else {
diff --git a/fxbarcode/qrcode/BC_QRCoderEncoder.cpp b/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
index 4f663e5..294bdca 100644
--- a/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
+++ b/fxbarcode/qrcode/BC_QRCoderEncoder.cpp
@@ -33,6 +33,7 @@
 #include "core/fxcrt/check.h"
 #include "core/fxcrt/check_op.h"
 #include "core/fxcrt/data_vector.h"
+#include "core/fxcrt/fx_extension.h"
 #include "core/fxcrt/fx_string.h"
 #include "core/fxcrt/stl_util.h"
 #include "fxbarcode/common/BC_CommonByteMatrix.h"
@@ -282,7 +283,7 @@
   bool hasNumeric = false;
   bool hasAlphaNumeric = false;
   for (size_t i = 0; i < content.GetLength(); i++) {
-    if (isdigit(content[i])) {
+    if (FXSYS_IsDecimalDigit(content[i])) {
       hasNumeric = true;
     } else if (GetAlphaNumericCode(content[i]) != -1) {
       hasAlphaNumeric = true;
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index 752dab7..59c65c3 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -6,7 +6,6 @@
 
 #include "fxjs/xfa/cfxjse_formcalc_context.h"
 
-#include <ctype.h>
 #include <math.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -509,7 +508,7 @@
 }
 
 bool IsPartOfNumber(char ch) {
-  return isdigit(ch) || ch == '-' || ch == '.';
+  return FXSYS_IsDecimalDigit(ch) || ch == '-' || ch == '.';
 }
 
 bool IsPartOfNumberW(wchar_t ch) {
@@ -3224,7 +3223,7 @@
       }
 
       while (uVal < bsUnitTemp.GetLength()) {
-        if (!isdigit(pChar[uVal]) && pChar[uVal] != '.') {
+        if (!FXSYS_IsDecimalDigit(pChar[uVal]) && pChar[uVal] != '.') {
           break;
         }
         ++uVal;
@@ -5175,7 +5174,7 @@
 
   std::array<char, 5> szYear = {};
   for (int32_t i = 0; i < 4; ++i) {
-    if (!isdigit(pData[i])) {
+    if (!FXSYS_IsDecimalDigit(pData[i])) {
       return false;
     }
     szYear[i] = pData[i];
@@ -5187,7 +5186,8 @@
 
   int32_t iStyle = pData[4] == '-' ? 1 : 0;
   size_t iPosOff = iStyle == 0 ? 4 : 5;
-  if (!isdigit(pData[iPosOff]) || !isdigit(pData[iPosOff + 1])) {
+  if (!FXSYS_IsDecimalDigit(pData[iPosOff]) ||
+      !FXSYS_IsDecimalDigit(pData[iPosOff + 1])) {
     return false;
   }
 
@@ -5210,7 +5210,8 @@
       return true;
     }
   }
-  if (!isdigit(pData[iPosOff]) || !isdigit(pData[iPosOff + 1])) {
+  if (!FXSYS_IsDecimalDigit(pData[iPosOff]) ||
+      !FXSYS_IsDecimalDigit(pData[iPosOff + 1])) {
     return false;
   }
 
@@ -5244,7 +5245,7 @@
   size_t iZone = 0;
   size_t i = 0;
   while (i < pData.size()) {
-    if (!isdigit(pData[i]) && pData[i] != ':') {
+    if (!FXSYS_IsDecimalDigit(pData[i]) && pData[i] != ':') {
       iZone = i;
       break;
     }
@@ -5260,7 +5261,8 @@
   while (iIndex + 1 < iZone) {
     szBuffer[0] = pData[iIndex];
     szBuffer[1] = pData[iIndex + 1];
-    if (!isdigit(szBuffer[0]) || !isdigit(szBuffer[1])) {
+    if (!FXSYS_IsDecimalDigit(szBuffer[0]) ||
+        !FXSYS_IsDecimalDigit(szBuffer[1])) {
       return false;
     }
     int32_t value = FXSYS_atoi(szBuffer);
@@ -5299,7 +5301,7 @@
     std::array<char, kSubSecondLength + 1> szMilliSeconds = {};
     for (int j = 0; j < kSubSecondLength; ++j) {
       char c = pData[iIndex + j];
-      if (!isdigit(c)) {
+      if (!FXSYS_IsDecimalDigit(c)) {
         return false;
       }
       szMilliSeconds[j] = c;
@@ -5325,7 +5327,8 @@
   while (iIndex + 1 < pData.size()) {
     szBuffer[0] = pData[iIndex];
     szBuffer[1] = pData[iIndex + 1];
-    if (!isdigit(szBuffer[0]) || !isdigit(szBuffer[1])) {
+    if (!FXSYS_IsDecimalDigit(szBuffer[0]) ||
+        !FXSYS_IsDecimalDigit(szBuffer[1])) {
       return false;
     }
     int32_t value = FXSYS_atoi(szBuffer);