Changeset 206281 in webkit
- Timestamp:
- Sep 22, 2016 4:41:56 PM (8 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JSTests/ChangeLog
r206268 r206281 1 2016-09-22 Mark Lam <mark.lam@apple.com> 2 3 Array.prototype.join should do overflow checks on string joins. 4 https://bugs.webkit.org/show_bug.cgi?id=162459 5 6 Reviewed by Saam Barati. 7 8 * stress/array-join-on-strings-need-overflow-checks.js: Added. 9 (assert): 10 (catch): 11 1 12 2016-09-22 Joseph Pecoraro <pecoraro@apple.com> 2 13 -
trunk/Source/JavaScriptCore/ChangeLog
r206274 r206281 1 2016-09-22 Mark Lam <mark.lam@apple.com> 2 3 Array.prototype.join should do overflow checks on string joins. 4 https://bugs.webkit.org/show_bug.cgi?id=162459 5 6 Reviewed by Saam Barati. 7 8 Change the 2 JSRopeString::create() functions that do joins to be private, and 9 force all clients of it to go through the jsString() utility functions that do 10 overflow checks before creating the ropes. 11 12 * dfg/DFGOperations.cpp: 13 * runtime/ArrayPrototype.cpp: 14 (JSC::slowJoin): 15 * runtime/JSString.h: 16 * runtime/Operations.h: 17 (JSC::jsString): 18 1 19 2016-09-22 Filip Pizlo <fpizlo@apple.com> 2 20 -
trunk/Source/JavaScriptCore/dfg/DFGOperations.cpp
r206267 r206281 53 53 #include "JSSet.h" 54 54 #include "ObjectConstructor.h" 55 #include "Operations.h" 55 56 #include "RegExpObject.h" 56 57 #include "Repatch.h" … … 1501 1502 VM& vm = exec->vm(); 1502 1503 NativeCallFrameTracer tracer(&vm, exec); 1503 auto scope = DECLARE_THROW_SCOPE(vm); 1504 1505 if (sumOverflows<int32_t>(left->length(), right->length())) { 1506 throwOutOfMemoryError(exec, scope); 1507 return nullptr; 1508 } 1509 1510 return JSRopeString::create(vm, left, right); 1504 1505 return jsString(exec, left, right); 1511 1506 } 1512 1507 … … 1515 1510 VM& vm = exec->vm(); 1516 1511 NativeCallFrameTracer tracer(&vm, exec); 1517 auto scope = DECLARE_THROW_SCOPE(vm); 1518 1519 if (sumOverflows<int32_t>(a->length(), b->length(), c->length())) { 1520 throwOutOfMemoryError(exec, scope); 1521 return nullptr; 1522 } 1523 1524 return JSRopeString::create(vm, a, b, c); 1512 1513 return jsString(exec, a, b, c); 1525 1514 } 1526 1515 … … 1536 1525 ASSERT(!scope.exception()); 1537 1526 1538 if (sumOverflows<int32_t>(str1->length(), str2->length())) { 1539 throwOutOfMemoryError(exec, scope); 1540 return nullptr; 1541 } 1542 1543 return JSRopeString::create(vm, str1, str2); 1527 scope.release(); 1528 return jsString(exec, str1, str2); 1544 1529 } 1545 1530 … … 1557 1542 ASSERT(!scope.exception()); 1558 1543 1559 if (sumOverflows<int32_t>(str1->length(), str2->length(), str3->length())) { 1560 throwOutOfMemoryError(exec, scope); 1561 return nullptr; 1562 } 1563 1564 return JSRopeString::create(vm, str1, str2, str3); 1544 scope.release(); 1545 return jsString(exec, str1, str2, str3); 1565 1546 } 1566 1547 -
trunk/Source/JavaScriptCore/runtime/ArrayPrototype.cpp
r205910 r206281 42 42 #include "ObjectConstructor.h" 43 43 #include "ObjectPrototype.h" 44 #include "Operations.h" 44 45 #include "StringRecursionChecker.h" 45 46 #include <algorithm> … … 547 548 // a. Let S be the String value produced by concatenating R and sep. 548 549 // d. Let R be a String value produced by concatenating S and next. 549 r = JSRopeString::create(vm, r, separator, next); 550 r = jsString(&exec, r, separator, next); 551 if (UNLIKELY(scope.exception())) 552 return JSValue(); 550 553 } 551 554 // 10. Return R. -
trunk/Source/JavaScriptCore/runtime/JSString.h
r204485 r206281 220 220 StringView unsafeView(ExecState&) const; 221 221 222 friend JS ValuejsString(ExecState*, JSString*, JSString*);222 friend JSString* jsString(ExecState*, JSString*, JSString*); 223 223 friend JSString* jsSubstring(ExecState*, JSString*, unsigned offset, unsigned length); 224 224 }; … … 278 278 { 279 279 Base::finishCreation(vm); 280 ASSERT(!sumOverflows<int32_t>(s1->length(), s2->length())); 280 281 m_length = s1->length() + s2->length(); 281 282 setIs8Bit(s1->is8Bit() && s2->is8Bit()); … … 289 290 { 290 291 Base::finishCreation(vm); 292 ASSERT(!sumOverflows<int32_t>(s1->length(), s2->length(), s3->length())); 291 293 m_length = s1->length() + s2->length() + s3->length(); 292 294 setIs8Bit(s1->is8Bit() && s2->is8Bit() && s3->is8Bit()); … … 358 360 359 361 public: 362 static JSString* create(VM& vm, ExecState* exec, JSString* base, unsigned offset, unsigned length) 363 { 364 JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm); 365 newString->finishCreation(vm, exec, base, offset, length); 366 return newString; 367 } 368 369 ALWAYS_INLINE static JSString* createSubstringOfResolved(VM& vm, JSString* base, unsigned offset, unsigned length) 370 { 371 JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm); 372 newString->finishCreationSubstringOfResolved(vm, base, offset, length); 373 return newString; 374 } 375 376 void visitFibers(SlotVisitor&); 377 378 static ptrdiff_t offsetOfFibers() { return OBJECT_OFFSETOF(JSRopeString, u); } 379 380 static const unsigned s_maxInternalRopeLength = 3; 381 382 private: 360 383 static JSString* create(VM& vm, JSString* s1, JSString* s2) 361 384 { … … 371 394 } 372 395 373 static JSString* create(VM& vm, ExecState* exec, JSString* base, unsigned offset, unsigned length)374 {375 JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);376 newString->finishCreation(vm, exec, base, offset, length);377 return newString;378 }379 380 ALWAYS_INLINE static JSString* createSubstringOfResolved(VM& vm, JSString* base, unsigned offset, unsigned length)381 {382 JSRopeString* newString = new (NotNull, allocateCell<JSRopeString>(vm.heap)) JSRopeString(vm);383 newString->finishCreationSubstringOfResolved(vm, base, offset, length);384 return newString;385 }386 387 void visitFibers(SlotVisitor&);388 389 static ptrdiff_t offsetOfFibers() { return OBJECT_OFFSETOF(JSRopeString, u); }390 391 static const unsigned s_maxInternalRopeLength = 3;392 393 private:394 396 friend JSValue jsStringFromRegisterArray(ExecState*, Register*, unsigned); 395 397 friend JSValue jsStringFromArguments(ExecState*, JSValue); … … 450 452 WriteBarrierBase<JSString> string; 451 453 } u[s_maxInternalRopeLength]; 454 455 456 friend JSString* jsString(ExecState*, JSString*, JSString*); 457 friend JSString* jsString(ExecState*, JSString*, JSString*, JSString*); 458 friend JSString* jsString(ExecState*, const String&, const String&, const String&); 452 459 }; 453 460 -
trunk/Source/JavaScriptCore/runtime/Operations.h
r205462 r206281 38 38 size_t normalizePrototypeChain(CallFrame*, Structure*); 39 39 40 ALWAYS_INLINE JS ValuejsString(ExecState* exec, JSString* s1, JSString* s2)40 ALWAYS_INLINE JSString* jsString(ExecState* exec, JSString* s1, JSString* s2) 41 41 { 42 42 VM& vm = exec->vm(); … … 49 49 if (!length2) 50 50 return s1; 51 if (sumOverflows<int32_t>(length1, length2)) 52 return throwOutOfMemoryError(exec, scope); 51 if (sumOverflows<int32_t>(length1, length2)) { 52 throwOutOfMemoryError(exec, scope); 53 return nullptr; 54 } 53 55 54 56 return JSRopeString::create(vm, s1, s2); 55 57 } 56 58 57 ALWAYS_INLINE JSValue jsString(ExecState* exec, const String& u1, const String& u2, const String& u3) 59 ALWAYS_INLINE JSString* jsString(ExecState* exec, JSString* s1, JSString* s2, JSString* s3) 60 { 61 VM& vm = exec->vm(); 62 auto scope = DECLARE_THROW_SCOPE(vm); 63 64 int32_t length1 = s1->length(); 65 if (!length1) { 66 scope.release(); 67 return jsString(exec, s2, s3); 68 } 69 int32_t length2 = s2->length(); 70 if (!length2) { 71 scope.release(); 72 return jsString(exec, s1, s3); 73 } 74 int32_t length3 = s3->length(); 75 if (!length3) { 76 scope.release(); 77 return jsString(exec, s1, s2); 78 } 79 80 if (sumOverflows<int32_t>(length1, length2, length3)) { 81 throwOutOfMemoryError(exec, scope); 82 return nullptr; 83 } 84 return JSRopeString::create(vm, s1, s2, s3); 85 } 86 87 ALWAYS_INLINE JSString* jsString(ExecState* exec, const String& u1, const String& u2, const String& u3) 58 88 { 59 89 VM* vm = &exec->vm(); … … 64 94 int32_t length3 = u3.length(); 65 95 66 if (length1 < 0 || length2 < 0 || length3 < 0) 67 return throwOutOfMemoryError(exec, scope); 96 if (length1 < 0 || length2 < 0 || length3 < 0) { 97 throwOutOfMemoryError(exec, scope); 98 return nullptr; 99 } 68 100 69 if (!length1) 101 if (!length1) { 102 scope.release(); 70 103 return jsString(exec, jsString(vm, u2), jsString(vm, u3)); 71 if (!length2) 104 } 105 if (!length2) { 106 scope.release(); 72 107 return jsString(exec, jsString(vm, u1), jsString(vm, u3)); 73 if (!length3) 108 } 109 if (!length3) { 110 scope.release(); 74 111 return jsString(exec, jsString(vm, u1), jsString(vm, u2)); 75 76 if (sumOverflows<int32_t>(length1, length2, length3)) 77 return throwOutOfMemoryError(exec, scope); 78 79 return JSRopeString::create(exec->vm(), jsString(vm, u1), jsString(vm, u2), jsString(vm, u3)); 112 } 113 114 if (sumOverflows<int32_t>(length1, length2, length3)) { 115 throwOutOfMemoryError(exec, scope); 116 return nullptr; 117 } 118 119 return JSRopeString::create(*vm, jsString(vm, u1), jsString(vm, u2), jsString(vm, u3)); 80 120 } 81 121
Note: See TracChangeset
for help on using the changeset viewer.