From 4c267997cd0ef3a8ec8176adb494bb75fa0bc062 Mon Sep 17 00:00:00 2001 From: "srdjan@google.com" Date: Wed, 23 Nov 2011 19:48:25 +0000 Subject: [PATCH] Fix bug 557: Disallow user side allocation of ImmutableArray. Also added "instantiation-checks" for some other VM-internal classes. Review URL: http://codereview.chromium.org//8648003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@1811 260f80e4-7a28-3924-810f-c04153c831b5 --- runtime/lib/array.dart | 5 +++++ runtime/lib/bool.dart | 4 ++++ runtime/lib/growable_array.dart | 5 +++++ runtime/lib/immutable_map.dart | 2 +- runtime/lib/integers.dart | 16 +++++++++++++++ runtime/lib/string.dart | 35 +++++++++++++++++++++++++++++++++ runtime/vm/parser.cc | 2 +- 7 files changed, 67 insertions(+), 2 deletions(-) diff --git a/runtime/lib/array.dart b/runtime/lib/array.dart index 89ccf2b3b60..5169d324864 100644 --- a/runtime/lib/array.dart +++ b/runtime/lib/array.dart @@ -161,6 +161,11 @@ class ObjectArray implements List { // the inline cache misses. class ImmutableArray implements List { + factory ImmutableArray._uninstantiable() { + throw const UnsupportedOperationException( + "ImmutableArray can only be allocated by the VM"); + } + T operator [](int index) native "ObjectArray_getIndexed"; void operator []=(int index, T value) { diff --git a/runtime/lib/bool.dart b/runtime/lib/bool.dart index 084a888bc88..871df4b8da4 100644 --- a/runtime/lib/bool.dart +++ b/runtime/lib/bool.dart @@ -3,4 +3,8 @@ // BSD-style license that can be found in the LICENSE file. class Bool implements bool { + factory Bool._uninstantiable() { + throw const UnsupportedOperationException( + "Bool can only be allocated by the VM"); + } } diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart index 2b6522811a6..e64e18ecf47 100644 --- a/runtime/lib/growable_array.dart +++ b/runtime/lib/growable_array.dart @@ -5,6 +5,11 @@ class GrowableObjectArray implements List { ObjectArray backingArray; + factory GrowableObjectArray._uninstantiable() { + throw const UnsupportedOperationException( + "GrowableObjectArray can only be allocated by the VM"); + } + void copyFrom(List src, int srcStart, int dstStart, int count) { Arrays.copy(src, srcStart, this, dstStart, count); } diff --git a/runtime/lib/immutable_map.dart b/runtime/lib/immutable_map.dart index 8500f2fb364..eefe1050944 100644 --- a/runtime/lib/immutable_map.dart +++ b/runtime/lib/immutable_map.dart @@ -6,7 +6,7 @@ class ImmutableMap implements Map { final ImmutableArray kvPairs_; - const ImmutableMap(ImmutableArray keyValuePairs) + const ImmutableMap._create(ImmutableArray keyValuePairs) : kvPairs_ = keyValuePairs; diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart index c98728a0cbf..eea8ab93426 100644 --- a/runtime/lib/integers.dart +++ b/runtime/lib/integers.dart @@ -5,6 +5,10 @@ // TODO(srdjan): fix limitations. // - shift amount must be a Smi. class IntegerImplementation { + factory IntegerImplementation._uninstantiable() { + throw const UnsupportedOperationException( + "IntegerImplementation can only be allocated by the VM"); + } num operator +(num other) { return other.addFromInteger(this); } @@ -156,6 +160,10 @@ class IntegerImplementation { } class Smi extends IntegerImplementation implements int { + factory Smi._uninstantiable() { + throw const UnsupportedOperationException( + "Smi can only be allocated by the VM"); + } int hashCode() { return this; } @@ -166,6 +174,10 @@ class Smi extends IntegerImplementation implements int { // Represents integers that cannot be represented by Smi but fit into 64bits. class Mint extends IntegerImplementation implements int { + factory Mint._uninstantiable() { + throw const UnsupportedOperationException( + "Mint can only be allocated by the VM"); + } int hashCode() { return this; } @@ -175,6 +187,10 @@ class Mint extends IntegerImplementation implements int { // A number that can be represented as Smi or Mint will never be represented as // Bigint. class Bigint extends IntegerImplementation implements int { + factory Bigint._uninstantiable() { + throw const UnsupportedOperationException( + "Bigint can only be allocated by the VM"); + } int hashCode() { return this; } diff --git a/runtime/lib/string.dart b/runtime/lib/string.dart index 701a37f857a..98ec9444c7a 100644 --- a/runtime/lib/string.dart +++ b/runtime/lib/string.dart @@ -8,6 +8,11 @@ */ class StringBase { + factory StringBase._uninstantiable() { + throw const UnsupportedOperationException( + "StringBase can't be instaniated"); + } + int hashCode() native "String_hashCode"; /** @@ -385,6 +390,11 @@ class StringBase { class OneByteString extends StringBase implements String { + factory OneByteString._uninstantiable() { + throw const UnsupportedOperationException( + "OneByteString can only be allocated by the VM"); + } + // Checks for one-byte whitespaces only. // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid // whitespaces for one byte strings. @@ -398,6 +408,11 @@ class OneByteString extends StringBase implements String { class TwoByteString extends StringBase implements String { + factory TwoByteString._uninstantiable() { + throw const UnsupportedOperationException( + "TwoByteString can only be allocated by the VM"); + } + // Checks for one-byte whitespaces only. // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid // whitespaces. Add checking for multi-byte whitespace codepoints. @@ -410,6 +425,11 @@ class TwoByteString extends StringBase implements String { class FourByteString extends StringBase implements String { + factory FourByteString._uninstantiable() { + throw const UnsupportedOperationException( + "FourByteString can only be allocated by the VM"); + } + // Checks for one-byte whitespaces only. // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid // whitespaces. Add checking for multi-byte whitespace codepoints. @@ -422,6 +442,11 @@ class FourByteString extends StringBase implements String { class ExternalOneByteString extends StringBase implements String { + factory ExternalOneByteString._uninstantiable() { + throw const UnsupportedOperationException( + "ExternalOneByteString can only be allocated by the VM"); + } + // Checks for one-byte whitespaces only. // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid // whitespaces for one byte strings. @@ -434,6 +459,11 @@ class ExternalOneByteString extends StringBase implements String { class ExternalTwoByteString extends StringBase implements String { + factory ExternalTwoByteString._uninstantiable() { + throw const UnsupportedOperationException( + "ExternalTwoByteString can only be allocated by the VM"); + } + // Checks for one-byte whitespaces only. // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid // whitespaces. Add checking for multi-byte whitespace codepoints. @@ -446,6 +476,11 @@ class ExternalTwoByteString extends StringBase implements String { class ExternalFourByteString extends StringBase implements String { + factory ExternalFourByteString._uninstantiable() { + throw const UnsupportedOperationException( + "ExternalFourByteString can only be allocated by the VM"); + } + // Checks for one-byte whitespaces only. // TODO(srdjan): Investigate if 0x85 (NEL) and 0xA0 (NBSP) are valid // whitespaces. Add checking for multi-byte whitespace codepoints. diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc index ffc04962060..289490741b1 100644 --- a/runtime/vm/parser.cc +++ b/runtime/vm/parser.cc @@ -35,7 +35,7 @@ static const char* kLiteralFactoryClassName = "_LiteralFactory"; static const char* kLiteralFactoryListFromLiteralName = "List.fromLiteral"; static const char* kLiteralFactoryMapFromLiteralName = "Map.fromLiteral"; static const char* kImmutableMapName = "ImmutableMap"; -static const char* kImmutableMapConstructorName = "ImmutableMap."; +static const char* kImmutableMapConstructorName = "ImmutableMap._create"; static const char* kStringClassName = "StringBase"; static const char* kInterpolateName = "_interpolate"; static const char* kThisName = "this";