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;