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

Side by Side Diff: src/value-serializer.cc

Issue 2399873002: ValueSerializer: Add more checks before trying to allocate memory for a dense array. (Closed)
Patch Set: be explicit to prevent signed/unsigned comparison Created 4 years, 2 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 | test/unittests/value-serializer-unittest.cc » ('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 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/value-serializer.h" 5 #include "src/value-serializer.h"
6 6
7 #include <type_traits> 7 #include <type_traits>
8 8
9 #include "src/base/logging.h" 9 #include "src/base/logging.h"
10 #include "src/conversions.h" 10 #include "src/conversions.h"
11 #include "src/factory.h" 11 #include "src/factory.h"
12 #include "src/handles-inl.h" 12 #include "src/handles-inl.h"
13 #include "src/isolate.h" 13 #include "src/isolate.h"
14 #include "src/objects-inl.h" 14 #include "src/objects-inl.h"
15 #include "src/objects.h" 15 #include "src/objects.h"
16 #include "src/transitions.h" 16 #include "src/transitions.h"
17 17
18 namespace v8 { 18 namespace v8 {
19 namespace internal { 19 namespace internal {
20 20
21 static const uint32_t kLatestVersion = 9; 21 static const uint32_t kLatestVersion = 9;
22 static const int kPretenureThreshold = 100 * KB; 22 static const int kPretenureThreshold = 100 * KB;
23 23
24 // More than 2^30 - 1 elements shouldn't be permitted in a dense array.
25 // This shouldn't be possible on the V8 heap anyhow
26 static const uint32_t kMaxDenseArrayLength = 0x3FFFFFFF;
Jakob Kummerow 2016/10/07 13:10:17 Why not FixedArray::kMaxLength?
jbroman 2016/10/11 16:37:27 OK, done. I have some vague unease about that valu
27
24 template <typename T> 28 template <typename T>
25 static size_t BytesNeededForVarint(T value) { 29 static size_t BytesNeededForVarint(T value) {
26 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value, 30 static_assert(std::is_integral<T>::value && std::is_unsigned<T>::value,
27 "Only unsigned integer types can be written as varints."); 31 "Only unsigned integer types can be written as varints.");
28 size_t result = 0; 32 size_t result = 0;
29 do { 33 do {
30 result++; 34 result++;
31 value >>= 7; 35 value >>= 7;
32 } while (value); 36 } while (value);
33 return result; 37 return result;
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 467
464 // To keep things simple, for now we decide between dense and sparse 468 // To keep things simple, for now we decide between dense and sparse
465 // serialization based on elements kind. A more principled heuristic could 469 // serialization based on elements kind. A more principled heuristic could
466 // count the elements, but would need to take care to note which indices 470 // count the elements, but would need to take care to note which indices
467 // existed (as only indices which were enumerable own properties at this point 471 // existed (as only indices which were enumerable own properties at this point
468 // should be serialized). 472 // should be serialized).
469 const bool should_serialize_densely = 473 const bool should_serialize_densely =
470 array->HasFastElements() && !array->HasFastHoleyElements(); 474 array->HasFastElements() && !array->HasFastHoleyElements();
471 475
472 if (should_serialize_densely) { 476 if (should_serialize_densely) {
477 DCHECK_LE(length, kMaxDenseArrayLength);
478
473 // TODO(jbroman): Distinguish between undefined and a hole (this can happen 479 // TODO(jbroman): Distinguish between undefined and a hole (this can happen
474 // if serializing one of the elements deletes another). This requires wire 480 // if serializing one of the elements deletes another). This requires wire
475 // format changes. 481 // format changes.
476 WriteTag(SerializationTag::kBeginDenseJSArray); 482 WriteTag(SerializationTag::kBeginDenseJSArray);
477 WriteVarint<uint32_t>(length); 483 WriteVarint<uint32_t>(length);
478 uint32_t i = 0; 484 uint32_t i = 0;
479 485
480 // Fast paths. Note that FAST_ELEMENTS in particular can bail due to the 486 // Fast paths. Note that FAST_ELEMENTS in particular can bail due to the
481 // structure of the elements changing. 487 // structure of the elements changing.
482 switch (array->GetElementsKind()) { 488 switch (array->GetElementsKind()) {
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 } 1164 }
1159 1165
1160 DCHECK(HasObjectWithID(id)); 1166 DCHECK(HasObjectWithID(id));
1161 return scope.CloseAndEscape(array); 1167 return scope.CloseAndEscape(array);
1162 } 1168 }
1163 1169
1164 MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() { 1170 MaybeHandle<JSArray> ValueDeserializer::ReadDenseJSArray() {
1165 // If we are at the end of the stack, abort. This function may recurse. 1171 // If we are at the end of the stack, abort. This function may recurse.
1166 STACK_CHECK(isolate_, MaybeHandle<JSArray>()); 1172 STACK_CHECK(isolate_, MaybeHandle<JSArray>());
1167 1173
1174 // We shouldn't permit an array larger than the biggest we can request from
1175 // V8. As an additional sanity check, since each entry will take at least one
1176 // byte to encode, if there are fewer bytes than that we can also fail fast.
1168 uint32_t length; 1177 uint32_t length;
1169 if (!ReadVarint<uint32_t>().To(&length)) return MaybeHandle<JSArray>(); 1178 if (!ReadVarint<uint32_t>().To(&length) || length > kMaxDenseArrayLength ||
1179 length > static_cast<size_t>(end_ - position_)) {
1180 return MaybeHandle<JSArray>();
1181 }
1170 1182
1171 uint32_t id = next_id_++; 1183 uint32_t id = next_id_++;
1172 HandleScope scope(isolate_); 1184 HandleScope scope(isolate_);
1173 Handle<JSArray> array = isolate_->factory()->NewJSArray( 1185 Handle<JSArray> array = isolate_->factory()->NewJSArray(
1174 FAST_HOLEY_ELEMENTS, length, length, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE, 1186 FAST_HOLEY_ELEMENTS, length, length, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE,
1175 pretenure_); 1187 pretenure_);
1176 AddObjectWithID(id, array); 1188 AddObjectWithID(id, array);
1177 1189
1178 Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate_); 1190 Handle<FixedArray> elements(FixedArray::cast(array->elements()), isolate_);
1179 for (uint32_t i = 0; i < length; i++) { 1191 for (uint32_t i = 0; i < length; i++) {
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
1724 if (stack.size() != 1) { 1736 if (stack.size() != 1) {
1725 isolate_->Throw(*isolate_->factory()->NewError( 1737 isolate_->Throw(*isolate_->factory()->NewError(
1726 MessageTemplate::kDataCloneDeserializationError)); 1738 MessageTemplate::kDataCloneDeserializationError));
1727 return MaybeHandle<Object>(); 1739 return MaybeHandle<Object>();
1728 } 1740 }
1729 return scope.CloseAndEscape(stack[0]); 1741 return scope.CloseAndEscape(stack[0]);
1730 } 1742 }
1731 1743
1732 } // namespace internal 1744 } // namespace internal
1733 } // namespace v8 1745 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/value-serializer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698