[shared-struct] Throw on duplicate field names

Bug: v8:12547, chromium:1380826
Change-Id: I02d662844d4598e29b994ac0e888c496bb8935ca
Fixed: chromium:1380826
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4006375
Commit-Queue: Adam Klein <adamk@chromium.org>
Reviewed-by: Adam Klein <adamk@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Auto-Submit: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#84071}
This commit is contained in:
Shu-yu Guo 2022-11-04 11:58:43 -07:00 committed by V8 LUCI CQ
parent 3cb0bbdd13
commit c82f221882
2 changed files with 34 additions and 0 deletions

View File

@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <unordered_set>
#include "src/builtins/builtins-utils-inl.h"
#include "src/objects/js-struct-inl.h"
#include "src/objects/property-details.h"
@ -15,6 +17,25 @@ constexpr int kMaxJSStructFields = 999;
// rely on DescriptorArrays and are hence limited to 1020 fields at most.
static_assert(kMaxJSStructFields <= kMaxNumberOfDescriptors);
namespace {
struct NameHandleHasher {
size_t operator()(Handle<Name> name) const { return name->hash(); }
};
struct UniqueNameHandleEqual {
bool operator()(Handle<Name> x, Handle<Name> y) const {
DCHECK(x->IsUniqueName());
DCHECK(y->IsUniqueName());
return *x == *y;
}
};
using UniqueNameHandleSet =
std::unordered_set<Handle<Name>, NameHandleHasher, UniqueNameHandleEqual>;
} // namespace
BUILTIN(SharedStructTypeConstructor) {
DCHECK(v8_flags.shared_string_table);
@ -43,6 +64,7 @@ BUILTIN(SharedStructTypeConstructor) {
num_properties, 0, AllocationType::kSharedOld);
// Build up the descriptor array.
UniqueNameHandleSet all_field_names;
for (int i = 0; i < num_properties; ++i) {
Handle<Object> raw_field_name;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
@ -53,6 +75,14 @@ BUILTIN(SharedStructTypeConstructor) {
Object::ToName(isolate, raw_field_name));
field_name = factory->InternalizeName(field_name);
// Check that there are no duplicates.
const bool is_duplicate = !all_field_names.insert(field_name).second;
if (is_duplicate) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kDuplicateTemplateProperty,
field_name));
}
// Shared structs' fields need to be aligned, so make it all tagged.
PropertyDetails details(
PropertyKind::kData, SEALED, PropertyLocation::kField,

View File

@ -90,3 +90,7 @@ let S = new SharedStructType(['field']);
for (let prop in s) propNames.push(prop);
assertArrayEquals(propNames, fieldNames);
})();
(function TestDuplicateFieldNames() {
assertThrows(() => new SharedStructType(['same', 'same']));
})();