Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: runtime/lib/integers_patch.dart

Issue 2987003002: [corelib] Add explicit overflow checks to int.parse (Closed)
Patch Set: Comments in Dart are converted to doc-comments Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tests/corelib_2/corelib_2.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 // Dart core library. 4 // Dart core library.
5 5
6 // VM implementation of int. 6 // VM implementation of int.
7 7
8 @patch 8 @patch
9 class int { 9 class int {
10 @patch 10 @patch
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 while (smallBlockSize >= blockSize) smallBlockSize -= blockSize; 125 while (smallBlockSize >= blockSize) smallBlockSize -= blockSize;
126 int result = 0; 126 int result = 0;
127 if (smallBlockSize > 0) { 127 if (smallBlockSize > 0) {
128 int blockEnd = start + smallBlockSize; 128 int blockEnd = start + smallBlockSize;
129 _Smi smi = _parseBlock(source, radix, start, blockEnd); 129 _Smi smi = _parseBlock(source, radix, start, blockEnd);
130 if (smi == null) return null; 130 if (smi == null) return null;
131 result = sign * smi; 131 result = sign * smi;
132 start = blockEnd; 132 start = blockEnd;
133 } 133 }
134 int multiplier = _PARSE_LIMITS[tableIndex + 1]; 134 int multiplier = _PARSE_LIMITS[tableIndex + 1];
135 int positiveOverflowLimit = 0;
136 int negativeOverflowLimit = 0;
137 if (_limitIntsTo64Bits) {
138 tableIndex = tableIndex << 1; // pre-multiply by 2 for simpler indexing
139 positiveOverflowLimit = _int64OverflowLimits[tableIndex];
140 if (positiveOverflowLimit == 0) {
141 positiveOverflowLimit =
142 _initInt64OverflowLimits(tableIndex, multiplier);
143 }
144 negativeOverflowLimit = _int64OverflowLimits[tableIndex + 1];
145 }
135 int blockEnd = start + blockSize; 146 int blockEnd = start + blockSize;
136 do { 147 do {
137 _Smi smi = _parseBlock(source, radix, start, blockEnd); 148 _Smi smi = _parseBlock(source, radix, start, blockEnd);
138 if (smi == null) return null; 149 if (smi == null) return null;
150 if (_limitIntsTo64Bits) {
151 if (result >= positiveOverflowLimit) {
152 if ((result > positiveOverflowLimit) ||
153 (smi > _int64OverflowLimits[tableIndex + 2])) {
154 return null;
155 }
156 } else if (result <= negativeOverflowLimit) {
157 if ((result < negativeOverflowLimit) ||
158 (smi > _int64OverflowLimits[tableIndex + 3])) {
159 return null;
160 }
161 }
162 }
139 result = (result * multiplier) + (sign * smi); 163 result = (result * multiplier) + (sign * smi);
140 start = blockEnd; 164 start = blockEnd;
141 blockEnd = start + blockSize; 165 blockEnd = start + blockSize;
142 } while (blockEnd <= end); 166 } while (blockEnd <= end);
143 return result; 167 return result;
144 } 168 }
145 169
146 // Parse block of digits into a Smi. 170 // Parse block of digits into a Smi.
147 static _Smi _parseBlock(String source, int radix, int start, int end) { 171 static _Smi _parseBlock(String source, int radix, int start, int end) {
148 _Smi result = 0; 172 _Smi result = 0;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 6, 481890304, 12, 232218265089212416, 223 6, 481890304, 12, 232218265089212416,
200 6, 594823321, 12, 353814783205469041, 224 6, 594823321, 12, 353814783205469041,
201 6, 729000000, 12, 531441000000000000, // radix: 30 225 6, 729000000, 12, 531441000000000000, // radix: 30
202 6, 887503681, 12, 787662783788549761, 226 6, 887503681, 12, 787662783788549761,
203 6, 1073741824, 12, 1152921504606846976, 227 6, 1073741824, 12, 1152921504606846976,
204 5, 39135393, 12, 1667889514952984961, 228 5, 39135393, 12, 1667889514952984961,
205 5, 45435424, 12, 2386420683693101056, 229 5, 45435424, 12, 2386420683693101056,
206 5, 52521875, 12, 3379220508056640625, // radix: 35 230 5, 52521875, 12, 3379220508056640625, // radix: 35
207 5, 60466176, 11, 131621703842267136, 231 5, 60466176, 11, 131621703842267136,
208 ]; 232 ];
233
234 /// Flag indicating if integers are limited by 64 bits
235 /// (`--limit-ints-to-64-bits` mode is enabled).
236 static const _limitIntsTo64Bits = ((1 << 64) == 0);
237
238 static const _maxInt64 = 0x7fffffffffffffff;
239 static const _minInt64 = -_maxInt64 - 1;
240
241 /// In the `--limit-ints-to-64-bits` mode calculation of the expression
242 ///
243 /// result = (result * multiplier) + (sign * smi)
244 ///
245 /// in `_parseRadix()` may overflow 64-bit integers. In such case,
246 /// `int.parse()` should stop with an error.
247 ///
248 /// This table is lazily filled with int64 overflow limits for result and smi.
249 /// For each multiplier from `_PARSE_LIMITS[tableIndex + 1]` this table
250 /// contains
251 ///
252 /// * `[tableIndex*2]` = positive limit for result
253 /// * `[tableIndex*2 + 1]` = negative limit for result
254 /// * `[tableIndex*2 + 2]` = limit for smi if result is exactly at positive li mit
255 /// * `[tableIndex*2 + 3]` = limit for smi if result is exactly at negative li mit
256 static final Int64List _int64OverflowLimits =
257 new Int64List(_PARSE_LIMITS.length * 2);
258
259 static int _initInt64OverflowLimits(int tableIndex, int multiplier) {
260 _int64OverflowLimits[tableIndex] = _maxInt64 ~/ multiplier;
261 _int64OverflowLimits[tableIndex + 1] = _minInt64 ~/ multiplier;
262 _int64OverflowLimits[tableIndex + 2] = _maxInt64.remainder(multiplier);
263 _int64OverflowLimits[tableIndex + 3] = -(_minInt64.remainder(multiplier));
264 return _int64OverflowLimits[tableIndex];
265 }
209 } 266 }
OLDNEW
« no previous file with comments | « no previous file | tests/corelib_2/corelib_2.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698