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

Side by Side Diff: src/runtime.cc

Issue 2868046: Fix crash: handle all flat string types in regexp replace. (Closed)
Patch Set: Review fixes Created 10 years, 5 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 | « src/objects.h ('k') | test/mjsunit/string-replace-with-empty.js » ('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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2266 matching lines...) Expand 10 before | Expand all | Expand 10 after
2277 matched = !match->IsNull(); 2277 matched = !match->IsNull();
2278 } while (matched); 2278 } while (matched);
2279 2279
2280 if (prev < length) { 2280 if (prev < length) {
2281 builder.AddSubjectSlice(prev, length); 2281 builder.AddSubjectSlice(prev, length);
2282 } 2282 }
2283 2283
2284 return *(builder.ToString()); 2284 return *(builder.ToString());
2285 } 2285 }
2286 2286
2287
2287 template <typename ResultSeqString> 2288 template <typename ResultSeqString>
2288 static Object* StringReplaceRegExpWithEmptyString(ResultSeqString* subject, 2289 static Object* StringReplaceRegExpWithEmptyString(String* subject,
2289 JSRegExp* regexp, 2290 JSRegExp* regexp,
2290 JSArray* last_match_info) { 2291 JSArray* last_match_info) {
2291 ASSERT(subject->IsFlat()); 2292 ASSERT(subject->IsFlat());
2292 2293
2293 HandleScope handles; 2294 HandleScope handles;
2294 2295
2295 Handle<String> subject_handle(subject); 2296 Handle<String> subject_handle(subject);
2296 Handle<JSRegExp> regexp_handle(regexp); 2297 Handle<JSRegExp> regexp_handle(regexp);
2297 Handle<JSArray> last_match_info_handle(last_match_info); 2298 Handle<JSArray> last_match_info_handle(last_match_info);
2298 Handle<Object> match = RegExpImpl::Exec(regexp_handle, 2299 Handle<Object> match = RegExpImpl::Exec(regexp_handle,
(...skipping 14 matching lines...) Expand all
2313 2314
2314 start = RegExpImpl::GetCapture(match_info_array, 0); 2315 start = RegExpImpl::GetCapture(match_info_array, 0);
2315 end = RegExpImpl::GetCapture(match_info_array, 1); 2316 end = RegExpImpl::GetCapture(match_info_array, 1);
2316 } 2317 }
2317 2318
2318 int length = subject->length(); 2319 int length = subject->length();
2319 int new_length = length - (end - start); 2320 int new_length = length - (end - start);
2320 if (new_length == 0) { 2321 if (new_length == 0) {
2321 return Heap::empty_string(); 2322 return Heap::empty_string();
2322 } 2323 }
2323 // TODO(sandholm) try to use types statically to determine this.
2324 Handle<ResultSeqString> answer; 2324 Handle<ResultSeqString> answer;
2325 if (subject_handle->IsAsciiRepresentation()) { 2325 if (ResultSeqString::kHasAsciiEncoding) {
2326 answer = 2326 answer =
2327 Handle<ResultSeqString>::cast(Factory::NewRawAsciiString(new_length)); 2327 Handle<ResultSeqString>::cast(Factory::NewRawAsciiString(new_length));
2328 } else { 2328 } else {
2329 answer = 2329 answer =
2330 Handle<ResultSeqString>::cast(Factory::NewRawTwoByteString(new_length)); 2330 Handle<ResultSeqString>::cast(Factory::NewRawTwoByteString(new_length));
2331 } 2331 }
2332 2332
2333 // If the regexp isn't global, only match once. 2333 // If the regexp isn't global, only match once.
2334 if (!regexp_handle->GetFlags().is_global()) { 2334 if (!regexp_handle->GetFlags().is_global()) {
2335 if (start > 0) { 2335 if (start > 0) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
2433 } 2433 }
2434 replacement = String::cast(flat_replacement); 2434 replacement = String::cast(flat_replacement);
2435 } 2435 }
2436 2436
2437 CONVERT_CHECKED(JSRegExp, regexp, args[1]); 2437 CONVERT_CHECKED(JSRegExp, regexp, args[1]);
2438 CONVERT_CHECKED(JSArray, last_match_info, args[3]); 2438 CONVERT_CHECKED(JSArray, last_match_info, args[3]);
2439 2439
2440 ASSERT(last_match_info->HasFastElements()); 2440 ASSERT(last_match_info->HasFastElements());
2441 2441
2442 if (replacement->length() == 0) { 2442 if (replacement->length() == 0) {
2443 if (subject->IsAsciiRepresentation()) { 2443 if (subject->IsAsciiRepresentation() || subject->HasOnlyAsciiChars()) {
Lasse Reichstein 2010/07/06 12:09:36 Does subject->IsAsciiRepresentation() imply subjec
Vitaly Repeshko 2010/07/06 12:22:39 Done.
2444 return StringReplaceRegExpWithEmptyString(SeqAsciiString::cast(subject), 2444 return StringReplaceRegExpWithEmptyString<SeqAsciiString>(
2445 regexp, 2445 subject, regexp, last_match_info);
2446 last_match_info);
2447 } else { 2446 } else {
2448 return StringReplaceRegExpWithEmptyString(SeqTwoByteString::cast(subject), 2447 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>(
2449 regexp, 2448 subject, regexp, last_match_info);
2450 last_match_info);
2451 } 2449 }
2452 } 2450 }
2453 2451
2454 return StringReplaceRegExpWithString(subject, 2452 return StringReplaceRegExpWithString(subject,
2455 regexp, 2453 regexp,
2456 replacement, 2454 replacement,
2457 last_match_info); 2455 last_match_info);
2458 } 2456 }
2459 2457
2460 2458
(...skipping 8077 matching lines...) Expand 10 before | Expand all | Expand 10 after
10538 } else { 10536 } else {
10539 // Handle last resort GC and make sure to allow future allocations 10537 // Handle last resort GC and make sure to allow future allocations
10540 // to grow the heap without causing GCs (if possible). 10538 // to grow the heap without causing GCs (if possible).
10541 Counters::gc_last_resort_from_js.Increment(); 10539 Counters::gc_last_resort_from_js.Increment();
10542 Heap::CollectAllGarbage(false); 10540 Heap::CollectAllGarbage(false);
10543 } 10541 }
10544 } 10542 }
10545 10543
10546 10544
10547 } } // namespace v8::internal 10545 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | test/mjsunit/string-replace-with-empty.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698