You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by am...@apache.org on 2019/02/21 16:25:15 UTC

[trafficserver] branch master updated: TextView: add overflow checking to svto_radix.

This is an automated email from the ASF dual-hosted git repository.

amc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 331d378  TextView: add overflow checking to svto_radix.
331d378 is described below

commit 331d3788f527659bd0633addfa4ca48b37d92c53
Author: Alan M. Carroll <am...@apache.org>
AuthorDate: Thu Jan 17 15:06:06 2019 -0600

    TextView: add overflow checking to svto_radix.
---
 include/tscpp/util/TextView.h | 24 ++++++++++++++++--------
 src/tscpp/util/TextView.cc    |  7 ++++++-
 2 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/include/tscpp/util/TextView.h b/include/tscpp/util/TextView.h
index 890ef30..ce620df 100644
--- a/include/tscpp/util/TextView.h
+++ b/include/tscpp/util/TextView.h
@@ -535,13 +535,18 @@ intmax_t svtoi(TextView src, TextView *parsed = nullptr, int base = 0);
  * @param src The source text. Updated during parsing.
  * @return The converted numeric value.
  *
- * This is a specialized function useful only where conversion performance is critical. It is used
- * inside @c svtoi for the common cases of 8, 10, and 16, therefore normally this isn't much more
- * performant in those cases than just @c svtoi. Because of this only positive values are parsed.
- * If determining the radix from the text or signed value parsing is needed, used @c svtoi.
+ * This is a specialized function useful only where conversion performance is critical, or for some
+ * other reason the numeric text has already been parsed out. The performance gains comes from
+ * templating the divisor which enables the compiler to optimize the multiplication (e.g., for
+ * powers of 2 shifts is used). It is used inside @c svtoi and @c svtou for the common cases of 8,
+ * 10, and 16, therefore normally this isn't much more performant than @c svtoi. Because of this
+ * only positive values are parsed. If determining the radix from the text or signed value parsing
+ * is needed, used @c svtoi.
  *
- * @a src is updated in place to indicate what characters were parsed. Parsing stops on the first
- * invalid digit, so any leading non-digit characters (e.g. whitespace) must already be removed.
+ * @a src is updated in place by removing parsed characters. Parsing stops on the first invalid
+ * digit, so any leading non-digit characters (e.g. whitespace) must already be removed. Overflow
+ * is detected and the first digit that would overflow is not parsed, and the maximum value is
+ * returned.
  */
 template <uintmax_t N>
 uintmax_t
@@ -551,8 +556,11 @@ svto_radix(ts::TextView &src)
   uintmax_t zret{0};
   uintmax_t v;
   while (src.size() && (0 <= (v = ts::svtoi_convert[static_cast<unsigned char>(*src)])) && v < N) {
-    zret *= N;
-    zret += v;
+    auto n = zret * N + v;
+    if (n < zret) { // overflow / wrap
+      return std::numeric_limits<uintmax_t>::max();
+    }
+    zret = n;
     ++src;
   }
   return zret;
diff --git a/src/tscpp/util/TextView.cc b/src/tscpp/util/TextView.cc
index b6b1135..4532b02 100644
--- a/src/tscpp/util/TextView.cc
+++ b/src/tscpp/util/TextView.cc
@@ -131,7 +131,12 @@ ts::svtoi(TextView src, TextView *out, int base)
       break;
     default:
       while (src.size() && (0 <= (v = svtoi_convert[static_cast<unsigned char>(*src)])) && v < base) {
-        zret = zret * base + v;
+        auto n = zret * base + v;
+        if (n < zret) {
+          zret = std::numeric_limits<uintmax_t>::max();
+          break; // overflow, stop parsing.
+        }
+        zret = n;
         ++src;
       }
       break;