Stop using fcvt() in AFPercent_Format().

fcvt() does not exist in some libc implementations and it is
inconsistent across implementations.

Replace it with a better implementation using snprintf(). Now many test
cases that would not run consistently before can be enabled.

BUG=pdfium:138

Change-Id: I2ec81f24d9f7defe90cc8b9dea3f856f267bd240
Reviewed-on: https://pdfium-review.googlesource.com/c/51075
Reviewed-by: Wei Li <weili@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/fxjs/cjs_publicmethods.cpp b/fxjs/cjs_publicmethods.cpp
index ded8622..11edff0 100644
--- a/fxjs/cjs_publicmethods.cpp
+++ b/fxjs/cjs_publicmethods.cpp
@@ -797,7 +797,17 @@
   if (iDec < 0 || iSepStyle < 0 || iSepStyle > kMaxSepStyle)
     return CJS_Result::Failure(JSMessage::kValueError);
 
+  // When the |iDec| value is too big, Acrobat will just return "%".
+  static constexpr int kDecLimit = 512;
+  // TODO(thestig): Calculate this once C++14 can be used to declare variables
+  // in constexpr functions.
+  static constexpr size_t kDigitsInDecLimit = 3;
   WideString& Value = pEvent->Value();
+  if (iDec > kDecLimit) {
+    Value = L"%";
+    return CJS_Result::Success();
+  }
+
   ByteString strValue = StrTrim(Value.ToDefANSI());
   if (strValue.IsEmpty())
     strValue = "0";
@@ -805,58 +815,46 @@
   // for processing decimal places
   double dValue = atof(strValue.c_str());
   dValue *= 100;
-  if (iDec > 0)
-    dValue += kDoubleCorrect;
 
-  int iDec2;
-  int iNegative = 0;
-  strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
-  if (strValue.IsEmpty()) {
-    dValue = 0;
-    strValue = fcvt(dValue, iDec, &iDec2, &iNegative);
-  }
+  size_t szNewSize;
+  {
+    // Figure out the format to use with FXSYS_snprintf() below.
+    // |format| is small because |iDec| is limited in size.
+    char format[sizeof("%.f") + kDigitsInDecLimit];  // e.g. "%.512f"
+    FXSYS_snprintf(format, sizeof(format), "%%.%df", iDec);
 
-  if (iDec2 < 0) {
-    ByteString zeros;
-    {
-      pdfium::span<char> zeros_ptr = zeros.GetBuffer(abs(iDec2));
-      std::fill(std::begin(zeros_ptr), std::end(zeros_ptr), '0');
+    // Calculate the new size for |strValue| and get a span.
+    size_t szBufferSize = iDec + 3;  // Negative sign, decimal point, and NUL.
+    double dValueCopy = fabs(dValue);
+    while (dValueCopy > 1) {
+      dValueCopy /= 10;
+      ++szBufferSize;
     }
-    zeros.ReleaseBuffer(abs(iDec2));
-    strValue = zeros + strValue;
-    iDec2 = 0;
-  }
-  int iMax = strValue.GetLength();
-  if (iDec2 > iMax) {
-    for (int iNum = 0; iNum <= iDec2 - iMax; iNum++)
-      strValue += '0';
 
-    iMax = iDec2 + 1;
+    // Write into |strValue|.
+    pdfium::span<char> span = strValue.GetBuffer(szBufferSize);
+    FXSYS_snprintf(span.data(), szBufferSize, format, dValue);
+    szNewSize = strlen(span.data());
   }
+  strValue.ReleaseBuffer(szNewSize);
 
-  // for processing seperator style
-  if (iDec2 < iMax) {
+  // for processing separator style
+  Optional<size_t> mark_pos = strValue.Find('.');
+  if (mark_pos.has_value()) {
     char mark = DecimalMarkForStyle(iSepStyle);
-    strValue.Insert(iDec2, mark);
-    iMax++;
-
-    if (iDec2 == 0)
-      strValue.Insert(iDec2, '0');
+    if (mark != '.')
+      strValue.SetAt(mark_pos.value(), mark);
   }
   bool bUseDigitSeparator = IsStyleWithDigitSeparator(iSepStyle);
   if (bUseDigitSeparator || IsStyleWithApostropheSeparator(iSepStyle)) {
     char cSeparator =
         bUseDigitSeparator ? DigitSeparatorForStyle(iSepStyle) : '\'';
-    for (int iDecPositive = iDec2 - 3; iDecPositive > 0; iDecPositive -= 3) {
-      strValue.Insert(iDecPositive, cSeparator);
-      iMax++;
-    }
+    int iEnd = mark_pos.value_or(strValue.GetLength());
+    int iStop = dValue < 0 ? 1 : 0;
+    for (int i = iEnd - 3; i > iStop; i -= 3)
+      strValue.Insert(i, cSeparator);
   }
 
-  // negative mark
-  if (iNegative)
-    strValue.InsertAtFront('-');
-
   if (bPercentPrepend)
     strValue.InsertAtFront('%');
   else
diff --git a/testing/resources/javascript/public_methods.in b/testing/resources/javascript/public_methods.in
index 6dca181..2cec741 100644
--- a/testing/resources/javascript/public_methods.in
+++ b/testing/resources/javascript/public_methods.in
@@ -200,16 +200,15 @@
       expectEventValue('', "AFPercent_Format(10, 0, 1)", "%0.0000000000");
       expectEventValue('', "AFPercent_Format(10, 0, 2)", "%0.0000000000");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 0, 0)", "98,765,432,100%");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 1, 0)", "98765432100%");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 2, 0)", "98.765.432.100%");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 0, 1)", "%98,765,432,100");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 1, 1)", "%98765432100");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 2, 1)", "%98.765.432.100");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 0, 2)", "%98,765,432,100");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 1, 2)", "%98765432100");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 2, 2)", "%98.765.432.100");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 0, 0)", "98,765,432,100%");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 1, 0)", "98765432100%");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 2, 0)", "98.765.432.100%");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 0, 1)", "%98,765,432,100");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 1, 1)", "%98765432100");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 2, 1)", "%98.765.432.100");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 0, 2)", "%98,765,432,100");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 1, 2)", "%98765432100");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 2, 2)", "%98.765.432.100");
 
       // InvalidArgsError
       expectError(0, "AFPercent_Format(-3, 0)");
@@ -220,13 +219,11 @@
       expectError(0, "AFPercent_Format(0, 50)");
       expectError(0, "AFPercent_Format(0, 51)");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue('', "AFPercent_Format(0, 0)", "0%");
-      // expectEventValue('', "AFPercent_Format(0, 1)", "0%");
-      // expectEventValue('', "AFPercent_Format(0, 2)", "0%");
-      // expectEventValue('', "AFPercent_Format(0, 3)", "0%");
-      // expectEventValue('', "AFPercent_Format(0, 4)", "0%");
-
+      expectEventValue('', "AFPercent_Format(0, 0)", "0%");
+      expectEventValue('', "AFPercent_Format(0, 1)", "0%");
+      expectEventValue('', "AFPercent_Format(0, 2)", "0%");
+      expectEventValue('', "AFPercent_Format(0, 3)", "0%");
+      expectEventValue('', "AFPercent_Format(0, 4)", "0%");
       expectEventValue('', "AFPercent_Format(1, 0)", "0.0%");
       expectEventValue('', "AFPercent_Format(1, 1)", "0.0%");
       expectEventValue('', "AFPercent_Format(1, 2)", "0,0%");
@@ -248,13 +245,11 @@
       expectEventValue('', "AFPercent_Format(10, 3)", "0,0000000000%");
       expectEventValue('', "AFPercent_Format(10, 4)", "0.0000000000%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(0, "AFPercent_Format(0, 0)", "0%");
-      // expectEventValue(0, "AFPercent_Format(0, 1)", "0%");
-      // expectEventValue(0, "AFPercent_Format(0, 2)", "0%");
-      // expectEventValue(0, "AFPercent_Format(0, 3)", "0%");
-      // expectEventValue(0, "AFPercent_Format(0, 4)", "0%");
-
+      expectEventValue(0, "AFPercent_Format(0, 0)", "0%");
+      expectEventValue(0, "AFPercent_Format(0, 1)", "0%");
+      expectEventValue(0, "AFPercent_Format(0, 2)", "0%");
+      expectEventValue(0, "AFPercent_Format(0, 3)", "0%");
+      expectEventValue(0, "AFPercent_Format(0, 4)", "0%");
       expectEventValue(0, "AFPercent_Format(1, 0)", "0.0%");
       expectEventValue(0, "AFPercent_Format(1, 1)", "0.0%");
       expectEventValue(0, "AFPercent_Format(1, 2)", "0,0%");
@@ -276,13 +271,11 @@
       expectEventValue(0, "AFPercent_Format(10, 3)", "0,0000000000%");
       expectEventValue(0, "AFPercent_Format(10, 4)", "0.0000000000%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(-5.1234, "AFPercent_Format(0, 0)", "-512%");
-      // expectEventValue(-5.1234, "AFPercent_Format(0, 1)", "-512%");
-      // expectEventValue(-5.1234, "AFPercent_Format(0, 2)", "-512%");
-      // expectEventValue(-5.1234, "AFPercent_Format(0, 3)", "-512%");
-      // expectEventValue(-5.1234, "AFPercent_Format(0, 4)", "-512%");
-
+      expectEventValue(-5.1234, "AFPercent_Format(0, 0)", "-512%");
+      expectEventValue(-5.1234, "AFPercent_Format(0, 1)", "-512%");
+      expectEventValue(-5.1234, "AFPercent_Format(0, 2)", "-512%");
+      expectEventValue(-5.1234, "AFPercent_Format(0, 3)", "-512%");
+      expectEventValue(-5.1234, "AFPercent_Format(0, 4)", "-512%");
       expectEventValue(-5.1234, "AFPercent_Format(1, 0)", "-512.3%");
       expectEventValue(-5.1234, "AFPercent_Format(1, 1)", "-512.3%");
       expectEventValue(-5.1234, "AFPercent_Format(1, 2)", "-512,3%");
@@ -304,13 +297,11 @@
       expectEventValue(-5.1234, "AFPercent_Format(10, 3)", "-512,3400000000%");
       expectEventValue(-5.1234, "AFPercent_Format(10, 4)", "-512.3400000000%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(5.1234, "AFPercent_Format(0, 0)", "512%");
-      // expectEventValue(5.1234, "AFPercent_Format(0, 1)", "512%");
-      // expectEventValue(5.1234, "AFPercent_Format(0, 2)", "512%");
-      // expectEventValue(5.1234, "AFPercent_Format(0, 3)", "512%");
-      // expectEventValue(5.1234, "AFPercent_Format(0, 4)", "512%");
-
+      expectEventValue(5.1234, "AFPercent_Format(0, 0)", "512%");
+      expectEventValue(5.1234, "AFPercent_Format(0, 1)", "512%");
+      expectEventValue(5.1234, "AFPercent_Format(0, 2)", "512%");
+      expectEventValue(5.1234, "AFPercent_Format(0, 3)", "512%");
+      expectEventValue(5.1234, "AFPercent_Format(0, 4)", "512%");
       expectEventValue(5.1234, "AFPercent_Format(1, 0)", "512.3%");
       expectEventValue(5.1234, "AFPercent_Format(1, 1)", "512.3%");
       expectEventValue(5.1234, "AFPercent_Format(1, 2)", "512,3%");
@@ -335,13 +326,11 @@
       expectEventValue(12.3456, "AFPercent_Format(1, 0)", "1,234.6%");
       expectEventValue(12.3456, "AFPercent_Format(4, 1)", "1234.5600%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(0.009876, "AFPercent_Format(0, 0)", "1%");
-      // expectEventValue(0.009876, "AFPercent_Format(0, 1)", "1%");
-      // expectEventValue(0.009876, "AFPercent_Format(0, 2)", "1%");
-      // expectEventValue(0.009876, "AFPercent_Format(0, 3)", "1%");
-      // expectEventValue(0.009876, "AFPercent_Format(0, 4)", "1%");
-
+      expectEventValue(0.009876, "AFPercent_Format(0, 0)", "1%");
+      expectEventValue(0.009876, "AFPercent_Format(0, 1)", "1%");
+      expectEventValue(0.009876, "AFPercent_Format(0, 2)", "1%");
+      expectEventValue(0.009876, "AFPercent_Format(0, 3)", "1%");
+      expectEventValue(0.009876, "AFPercent_Format(0, 4)", "1%");
       expectEventValue(0.009876, "AFPercent_Format(1, 0)", "1.0%");
       expectEventValue(0.009876, "AFPercent_Format(1, 1)", "1.0%");
       expectEventValue(0.009876, "AFPercent_Format(1, 2)", "1,0%");
@@ -363,13 +352,11 @@
       expectEventValue(0.009876, "AFPercent_Format(10, 3)", "0,9876000000%");
       expectEventValue(0.009876, "AFPercent_Format(10, 4)", "0.9876000000%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 0)", "98,765,432,100%");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 1)", "98765432100%");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 2)", "98.765.432.100%");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 3)", "98765432100%");
-      // expectEventValue(987654321.001234, "AFPercent_Format(0, 4)", "98'765'432'100%");
-
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 0)", "98,765,432,100%");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 1)", "98765432100%");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 2)", "98.765.432.100%");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 3)", "98765432100%");
+      expectEventValue(987654321.001234, "AFPercent_Format(0, 4)", "98'765'432'100%");
       expectEventValue(987654321.001234, "AFPercent_Format(1, 0)", "98,765,432,100.1%");
       expectEventValue(987654321.001234, "AFPercent_Format(1, 1)", "98765432100.1%");
       expectEventValue(987654321.001234, "AFPercent_Format(1, 2)", "98.765.432.100,1%");
@@ -391,13 +378,11 @@
       expectEventValue(987654321.001234, "AFPercent_Format(10, 3)", "98765432100,1234130859%");
       expectEventValue(987654321.001234, "AFPercent_Format(10, 4)", "98'765'432'100.1234130859%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(987654321, "AFPercent_Format(0, 0)", "98,765,432,100%");
-      // expectEventValue(987654321, "AFPercent_Format(0, 1)", "98765432100%");
-      // expectEventValue(987654321, "AFPercent_Format(0, 2)", "98.765.432.100%");
-      // expectEventValue(987654321, "AFPercent_Format(0, 3)", "98765432100%");
-      // expectEventValue(987654321, "AFPercent_Format(0, 4)", "98'765'432'100%");
-
+      expectEventValue(987654321, "AFPercent_Format(0, 0)", "98,765,432,100%");
+      expectEventValue(987654321, "AFPercent_Format(0, 1)", "98765432100%");
+      expectEventValue(987654321, "AFPercent_Format(0, 2)", "98.765.432.100%");
+      expectEventValue(987654321, "AFPercent_Format(0, 3)", "98765432100%");
+      expectEventValue(987654321, "AFPercent_Format(0, 4)", "98'765'432'100%");
       expectEventValue(987654321, "AFPercent_Format(1, 0)", "98,765,432,100.0%");
       expectEventValue(987654321, "AFPercent_Format(1, 1)", "98765432100.0%");
       expectEventValue(987654321, "AFPercent_Format(1, 2)", "98.765.432.100,0%");
@@ -430,16 +415,14 @@
       // expectEventValue(0.0000001, "AFPercent_Format(1, 0)", "-170.0%");
       // expectEventValue(0.00000001, "AFPercent_Format(1, 0)", "-180.0%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(0, "AFPercent_Format(20, 0)", "0.00000000000000000000%");
-      // expectEventValue(0, "AFPercent_Format(308, 0)", "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%");
+      expectEventValue(0, "AFPercent_Format(20, 0)", "0.00000000000000000000%");
+      expectEventValue(0, "AFPercent_Format(308, 0)", "0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%");
       // Acrobat starts failing here.
       // expectEventValue(0, "AFPercent_Format(309, 0)", "-1.#IND000...000%");
 
-      // Inconsistent with PDFium due to bug 138.
-      // expectEventValue(0.000001, "AFPercent_Format(308, 0)", "0.00009999999999999999123964644631712417321978136897087097167968750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%");
+      expectEventValue(0.000001, "AFPercent_Format(308, 0)", "0.00009999999999999999123964644631712417321978136897087097167968750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%");
       // After 512, Acrobat probably ran out of buffer space.
-      // expectEventValue(0, "AFPercent_Format(513, 0)", "%");
+      expectEventValue(0, "AFPercent_Format(513, 0)", "%");
 
       app.alert("**********************");
 
diff --git a/testing/resources/javascript/public_methods_expected.txt b/testing/resources/javascript/public_methods_expected.txt
index 07cac56..d6b2566 100644
--- a/testing/resources/javascript/public_methods_expected.txt
+++ b/testing/resources/javascript/public_methods_expected.txt
@@ -69,6 +69,15 @@
 Alert: PASS: AFPercent_Format(10, 0, 0) = 0.0000000000%
 Alert: PASS: AFPercent_Format(10, 0, 1) = %0.0000000000
 Alert: PASS: AFPercent_Format(10, 0, 2) = %0.0000000000
+Alert: PASS: AFPercent_Format(0, 0, 0) = 98,765,432,100%
+Alert: PASS: AFPercent_Format(0, 1, 0) = 98765432100%
+Alert: PASS: AFPercent_Format(0, 2, 0) = 98.765.432.100%
+Alert: PASS: AFPercent_Format(0, 0, 1) = %98,765,432,100
+Alert: PASS: AFPercent_Format(0, 1, 1) = %98765432100
+Alert: PASS: AFPercent_Format(0, 2, 1) = %98.765.432.100
+Alert: PASS: AFPercent_Format(0, 0, 2) = %98,765,432,100
+Alert: PASS: AFPercent_Format(0, 1, 2) = %98765432100
+Alert: PASS: AFPercent_Format(0, 2, 2) = %98.765.432.100
 Alert: PASS: AFPercent_Format(-3, 0) threw AFPercent_Format: Incorrect parameter value.
 Alert: PASS: AFPercent_Format(-3, 1) threw AFPercent_Format: Incorrect parameter value.
 Alert: PASS: AFPercent_Format(-1, 3) threw AFPercent_Format: Incorrect parameter value.
@@ -76,6 +85,11 @@
 Alert: PASS: AFPercent_Format(0, -1) threw AFPercent_Format: Incorrect parameter value.
 Alert: PASS: AFPercent_Format(0, 50) threw AFPercent_Format: Incorrect parameter value.
 Alert: PASS: AFPercent_Format(0, 51) threw AFPercent_Format: Incorrect parameter value.
+Alert: PASS: AFPercent_Format(0, 0) = 0%
+Alert: PASS: AFPercent_Format(0, 1) = 0%
+Alert: PASS: AFPercent_Format(0, 2) = 0%
+Alert: PASS: AFPercent_Format(0, 3) = 0%
+Alert: PASS: AFPercent_Format(0, 4) = 0%
 Alert: PASS: AFPercent_Format(1, 0) = 0.0%
 Alert: PASS: AFPercent_Format(1, 1) = 0.0%
 Alert: PASS: AFPercent_Format(1, 2) = 0,0%
@@ -96,6 +110,11 @@
 Alert: PASS: AFPercent_Format(10, 2) = 0,0000000000%
 Alert: PASS: AFPercent_Format(10, 3) = 0,0000000000%
 Alert: PASS: AFPercent_Format(10, 4) = 0.0000000000%
+Alert: PASS: AFPercent_Format(0, 0) = 0%
+Alert: PASS: AFPercent_Format(0, 1) = 0%
+Alert: PASS: AFPercent_Format(0, 2) = 0%
+Alert: PASS: AFPercent_Format(0, 3) = 0%
+Alert: PASS: AFPercent_Format(0, 4) = 0%
 Alert: PASS: AFPercent_Format(1, 0) = 0.0%
 Alert: PASS: AFPercent_Format(1, 1) = 0.0%
 Alert: PASS: AFPercent_Format(1, 2) = 0,0%
@@ -116,6 +135,11 @@
 Alert: PASS: AFPercent_Format(10, 2) = 0,0000000000%
 Alert: PASS: AFPercent_Format(10, 3) = 0,0000000000%
 Alert: PASS: AFPercent_Format(10, 4) = 0.0000000000%
+Alert: PASS: AFPercent_Format(0, 0) = -512%
+Alert: PASS: AFPercent_Format(0, 1) = -512%
+Alert: PASS: AFPercent_Format(0, 2) = -512%
+Alert: PASS: AFPercent_Format(0, 3) = -512%
+Alert: PASS: AFPercent_Format(0, 4) = -512%
 Alert: PASS: AFPercent_Format(1, 0) = -512.3%
 Alert: PASS: AFPercent_Format(1, 1) = -512.3%
 Alert: PASS: AFPercent_Format(1, 2) = -512,3%
@@ -136,6 +160,11 @@
 Alert: PASS: AFPercent_Format(10, 2) = -512,3400000000%
 Alert: PASS: AFPercent_Format(10, 3) = -512,3400000000%
 Alert: PASS: AFPercent_Format(10, 4) = -512.3400000000%
+Alert: PASS: AFPercent_Format(0, 0) = 512%
+Alert: PASS: AFPercent_Format(0, 1) = 512%
+Alert: PASS: AFPercent_Format(0, 2) = 512%
+Alert: PASS: AFPercent_Format(0, 3) = 512%
+Alert: PASS: AFPercent_Format(0, 4) = 512%
 Alert: PASS: AFPercent_Format(1, 0) = 512.3%
 Alert: PASS: AFPercent_Format(1, 1) = 512.3%
 Alert: PASS: AFPercent_Format(1, 2) = 512,3%
@@ -158,6 +187,11 @@
 Alert: PASS: AFPercent_Format(10, 4) = 512.3400000000%
 Alert: PASS: AFPercent_Format(1, 0) = 1,234.6%
 Alert: PASS: AFPercent_Format(4, 1) = 1234.5600%
+Alert: PASS: AFPercent_Format(0, 0) = 1%
+Alert: PASS: AFPercent_Format(0, 1) = 1%
+Alert: PASS: AFPercent_Format(0, 2) = 1%
+Alert: PASS: AFPercent_Format(0, 3) = 1%
+Alert: PASS: AFPercent_Format(0, 4) = 1%
 Alert: PASS: AFPercent_Format(1, 0) = 1.0%
 Alert: PASS: AFPercent_Format(1, 1) = 1.0%
 Alert: PASS: AFPercent_Format(1, 2) = 1,0%
@@ -178,6 +212,11 @@
 Alert: PASS: AFPercent_Format(10, 2) = 0,9876000000%
 Alert: PASS: AFPercent_Format(10, 3) = 0,9876000000%
 Alert: PASS: AFPercent_Format(10, 4) = 0.9876000000%
+Alert: PASS: AFPercent_Format(0, 0) = 98,765,432,100%
+Alert: PASS: AFPercent_Format(0, 1) = 98765432100%
+Alert: PASS: AFPercent_Format(0, 2) = 98.765.432.100%
+Alert: PASS: AFPercent_Format(0, 3) = 98765432100%
+Alert: PASS: AFPercent_Format(0, 4) = 98'765'432'100%
 Alert: PASS: AFPercent_Format(1, 0) = 98,765,432,100.1%
 Alert: PASS: AFPercent_Format(1, 1) = 98765432100.1%
 Alert: PASS: AFPercent_Format(1, 2) = 98.765.432.100,1%
@@ -198,6 +237,11 @@
 Alert: PASS: AFPercent_Format(10, 2) = 98.765.432.100,1234130859%
 Alert: PASS: AFPercent_Format(10, 3) = 98765432100,1234130859%
 Alert: PASS: AFPercent_Format(10, 4) = 98'765'432'100.1234130859%
+Alert: PASS: AFPercent_Format(0, 0) = 98,765,432,100%
+Alert: PASS: AFPercent_Format(0, 1) = 98765432100%
+Alert: PASS: AFPercent_Format(0, 2) = 98.765.432.100%
+Alert: PASS: AFPercent_Format(0, 3) = 98765432100%
+Alert: PASS: AFPercent_Format(0, 4) = 98'765'432'100%
 Alert: PASS: AFPercent_Format(1, 0) = 98,765,432,100.0%
 Alert: PASS: AFPercent_Format(1, 1) = 98765432100.0%
 Alert: PASS: AFPercent_Format(1, 2) = 98.765.432.100,0%
@@ -224,6 +268,10 @@
 Alert: PASS: AFPercent_Format(1, 0) = 0.0%
 Alert: PASS: AFPercent_Format(1, 0) = 0.0%
 Alert: PASS: AFPercent_Format(10, 2) = 0,0001000000%
+Alert: PASS: AFPercent_Format(20, 0) = 0.00000000000000000000%
+Alert: PASS: AFPercent_Format(308, 0) = 0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%
+Alert: PASS: AFPercent_Format(308, 0) = 0.00009999999999999999123964644631712417321978136897087097167968750000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000%
+Alert: PASS: AFPercent_Format(513, 0) = %
 Alert: **********************
 Alert: PASS: AFPercent_Keystroke() threw AFPercent_Keystroke: Incorrect number of parameters passed to function.
 Alert: PASS: AFPercent_Keystroke(1) threw AFPercent_Keystroke: Incorrect number of parameters passed to function.