Rewrite ParsePageRangeString to make saner.

One ill-formatted test now fails.

Change-Id: I1fe6b1a0896643260e319665a3fe7777aa29ab5b
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/79023
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/cpdfsdk_helpers.cpp b/fpdfsdk/cpdfsdk_helpers.cpp
index 3711658..2f8c54e 100644
--- a/fpdfsdk/cpdfsdk_helpers.cpp
+++ b/fpdfsdk/cpdfsdk_helpers.cpp
@@ -454,54 +454,38 @@
 
 std::vector<uint32_t> ParsePageRangeString(const ByteString& bsPageRange,
                                            uint32_t nCount) {
-  ByteString bsStrippedPageRange = bsPageRange;
-  bsStrippedPageRange.Remove(' ');
-  size_t nLength = bsStrippedPageRange.GetLength();
-  if (nLength == 0)
-    return std::vector<uint32_t>();
-
-  static const ByteString cbCompareString("0123456789-,");
-  for (size_t i = 0; i < nLength; ++i) {
-    if (!cbCompareString.Contains(bsStrippedPageRange[i]))
+  ByteStringView alphabet(" 0123456789-,");
+  for (const auto& ch : bsPageRange) {
+    if (!alphabet.Contains(ch))
       return std::vector<uint32_t>();
   }
 
-  ByteString cbMidRange;
-  size_t nStringFrom = 0;
-  size_t nStringTo = 0;
-  std::vector<uint32_t> pageArray;
-  while (nStringTo < nLength) {
-    nStringTo = bsStrippedPageRange.Find(',', nStringFrom).value_or(nLength);
-    cbMidRange =
-        bsStrippedPageRange.Substr(nStringFrom, nStringTo - nStringFrom);
-    Optional<size_t> nDashPosition = cbMidRange.Find('-');
-    if (nDashPosition) {
-      size_t nMid = nDashPosition.value();
-      uint32_t nStartPageNum = pdfium::base::checked_cast<uint32_t>(
-          atoi(cbMidRange.First(nMid).c_str()));
-      if (nStartPageNum == 0)
-        return std::vector<uint32_t>();
+  ByteString bsStrippedPageRange = bsPageRange;
+  bsStrippedPageRange.Remove(' ');
 
-      ++nMid;
-      size_t nEnd = cbMidRange.GetLength() - nMid;
-      if (nEnd == 0)
+  std::vector<uint32_t> results;
+  for (const auto& entry : fxcrt::Split(bsStrippedPageRange, ',')) {
+    std::vector<ByteString> args = fxcrt::Split(entry, '-');
+    if (args.size() == 1) {
+      uint32_t page_num =
+          pdfium::base::checked_cast<uint32_t>(atoi(args[0].c_str()));
+      if (page_num == 0 || page_num > nCount)
         return std::vector<uint32_t>();
-
-      uint32_t nEndPageNum = pdfium::base::checked_cast<uint32_t>(
-          atoi(cbMidRange.Substr(nMid, nEnd).c_str()));
-      if (nStartPageNum > nEndPageNum || nEndPageNum > nCount)
+      results.push_back(page_num);
+    } else if (args.size() == 2) {
+      uint32_t first_num =
+          pdfium::base::checked_cast<uint32_t>(atoi(args[0].c_str()));
+      if (first_num == 0)
         return std::vector<uint32_t>();
-
-      for (uint32_t i = nStartPageNum; i <= nEndPageNum; ++i)
-        pageArray.push_back(i);
+      uint32_t last_num =
+          pdfium::base::checked_cast<uint32_t>(atoi(args[1].c_str()));
+      if (last_num == 0 || first_num > last_num || last_num > nCount)
+        return std::vector<uint32_t>();
+      for (uint32_t i = first_num; i <= last_num; ++i)
+        results.push_back(i);
     } else {
-      uint32_t nPageNum =
-          pdfium::base::checked_cast<uint32_t>(atoi(cbMidRange.c_str()));
-      if (nPageNum <= 0 || nPageNum > nCount)
-        return std::vector<uint32_t>();
-      pageArray.push_back(nPageNum);
+      return std::vector<uint32_t>();
     }
-    nStringFrom = nStringTo + 1;
   }
-  return pageArray;
+  return results;
 }
diff --git a/fpdfsdk/cpdfsdk_helpers_unittest.cpp b/fpdfsdk/cpdfsdk_helpers_unittest.cpp
index 27afd15..21b0061 100644
--- a/fpdfsdk/cpdfsdk_helpers_unittest.cpp
+++ b/fpdfsdk/cpdfsdk_helpers_unittest.cpp
@@ -63,6 +63,7 @@
   EXPECT_EQ(std::vector<uint32_t>({}), ParsePageRangeString("0,1", 10));
   EXPECT_EQ(std::vector<uint32_t>({}), ParsePageRangeString("1,0", 10));
   EXPECT_EQ(std::vector<uint32_t>({}), ParsePageRangeString("1-2,,,,3-4", 10));
+  EXPECT_EQ(std::vector<uint32_t>({}), ParsePageRangeString("1-2-", 10));
   EXPECT_EQ(std::vector<uint32_t>({1}), ParsePageRangeString("1-1", 10));
   EXPECT_EQ(std::vector<uint32_t>{1}, ParsePageRangeString("1", 1));
   EXPECT_EQ(std::vector<uint32_t>({1, 2, 3, 4}),
@@ -71,7 +72,6 @@
             ParsePageRangeString("1- 4", 4));
   EXPECT_EQ(std::vector<uint32_t>({1, 2, 3, 4}),
             ParsePageRangeString("1 -4", 4));
-  EXPECT_EQ(std::vector<uint32_t>({1, 2}), ParsePageRangeString("1-2-", 10));
   EXPECT_EQ(std::vector<uint32_t>({1, 2}), ParsePageRangeString("1,2", 10));
   EXPECT_EQ(std::vector<uint32_t>({2, 1}), ParsePageRangeString("2,1", 10));
   EXPECT_EQ(std::vector<uint32_t>({1, 50, 2}),