@@ -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.
191191template <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
240243template <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