Skip to content

Commit 62ee324

Browse files
pthierV8 LUCI CQ
authored andcommitted
[regexp] Use uint32_t over int in EscapeRegExpSource
While escaping the regexp source, a regular signed int might overflow, while an uint32_t can always hold the maximum length for the escaped source. Fixed: 420697404 Change-Id: I61084b93d51a2729204332b4285922fd82ee8fc7 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/6611425 Reviewed-by: Jakob Linke <[email protected]> Auto-Submit: Patrick Thier <[email protected]> Commit-Queue: Patrick Thier <[email protected]> Cr-Commit-Position: refs/heads/main@{#100636}
1 parent 4228bca commit 62ee324

1 file changed

Lines changed: 18 additions & 12 deletions

File tree

src/objects/js-regexp.cc

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,14 @@ bool IsLineTerminator(int c) {
189189
// WriteEscapedRegExpSource into a single function to deduplicate dispatch logic
190190
// and move related code closer to each other.
191191
template <typename Char>
192-
int CountAdditionalEscapeChars(DirectHandle<String> source,
193-
bool* needs_escapes_out) {
192+
uint32_t CountAdditionalEscapeChars(DirectHandle<String> source,
193+
bool* needs_escapes_out) {
194194
DisallowGarbageCollection no_gc;
195-
int escapes = 0;
195+
uint32_t escapes = 0;
196+
// The maximum growth-factor is 5 (for \u2028 and \u2029). Make sure that we
197+
// won't overflow |escapes| given the current constraints on string length.
198+
static_assert(uint64_t{String::kMaxLength} * 5 <
199+
std::numeric_limits<decltype(escapes)>::max());
196200
bool needs_escapes = false;
197201
bool in_character_class = false;
198202
base::Vector<const Char> src = source->GetCharVector<Char>(no_gc);
@@ -231,14 +235,14 @@ int CountAdditionalEscapeChars(DirectHandle<String> source,
231235
}
232236
}
233237
DCHECK(!in_character_class);
234-
DCHECK_GE(escapes, 0);
235238
DCHECK_IMPLIES(escapes != 0, needs_escapes);
236239
*needs_escapes_out = needs_escapes;
237240
return escapes;
238241
}
239242

240243
template <typename Char>
241-
void WriteStringToCharVector(base::Vector<Char> v, int* d, const char* string) {
244+
void WriteStringToCharVector(base::Vector<Char> v, uint32_t* d,
245+
const char* string) {
242246
int s = 0;
243247
while (string[s] != '\0') v[(*d)++] = string[s++];
244248
}
@@ -249,21 +253,21 @@ DirectHandle<StringType> WriteEscapedRegExpSource(
249253
DisallowGarbageCollection no_gc;
250254
base::Vector<const Char> src = source->GetCharVector<Char>(no_gc);
251255
base::Vector<Char> dst(result->GetChars(no_gc), result->length());
252-
int s = 0;
253-
int d = 0;
256+
uint32_t s = 0;
257+
uint32_t d = 0;
254258
bool in_character_class = false;
255-
while (s < src.length()) {
259+
while (s < src.size()) {
256260
const Char c = src[s];
257261
if (c == '\\') {
258-
if (s + 1 < src.length() && IsLineTerminator(src[s + 1])) {
262+
if (s + 1 < src.size() && IsLineTerminator(src[s + 1])) {
259263
// This '\' is ignored since the next character itself will be escaped.
260264
s++;
261265
continue;
262266
} else {
263267
// Escape. Copy this and next character.
264268
dst[d++] = src[s++];
265269
}
266-
if (s == src.length()) break;
270+
if (s == src.size()) break;
267271
} else if (c == '/' && !in_character_class) {
268272
// Not escaped forward-slash needs escape.
269273
dst[d++] = '\\';
@@ -303,11 +307,13 @@ MaybeDirectHandle<String> EscapeRegExpSource(Isolate* isolate,
303307
if (source->length() == 0) return isolate->factory()->query_colon_string();
304308
bool one_byte = String::IsOneByteRepresentationUnderneath(*source);
305309
bool needs_escapes = false;
306-
int additional_escape_chars =
310+
uint32_t additional_escape_chars =
307311
one_byte ? CountAdditionalEscapeChars<uint8_t>(source, &needs_escapes)
308312
: CountAdditionalEscapeChars<base::uc16>(source, &needs_escapes);
309313
if (!needs_escapes) return source;
310-
int length = source->length() + additional_escape_chars;
314+
DCHECK_LE(static_cast<uint64_t>(source->length()) + additional_escape_chars,
315+
std::numeric_limits<uint32_t>::max());
316+
uint32_t length = source->length() + additional_escape_chars;
311317
if (one_byte) {
312318
DirectHandle<SeqOneByteString> result;
313319
ASSIGN_RETURN_ON_EXCEPTION(isolate, result,

0 commit comments

Comments
 (0)