From 56141b82ad4e45442a0472c05cd0dc14aa5ab382 Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Tue, 8 Nov 2011 14:18:29 -0800 Subject: [PATCH] Bug 700802 - Define private overrides of all JSString methods with vacuous behavior for a given subclass, on that subclass. This will prevent someone from accidentally attempting to, say, linearize a linearly-typed string. r=luke --- js/src/vm/String-inl.h | 6 ++--- js/src/vm/String.cpp | 2 +- js/src/vm/String.h | 57 ++++++++++++++++++++++++++++++++---------- 3 files changed, 48 insertions(+), 17 deletions(-) diff --git a/js/src/vm/String-inl.h b/js/src/vm/String-inl.h index 68c66a20d80..b12732ae07c 100644 --- a/js/src/vm/String-inl.h +++ b/js/src/vm/String-inl.h @@ -359,15 +359,15 @@ JSFlatString::finalize(JSRuntime *rt) inline void JSShortString::finalize(JSContext *cx) { - JS_ASSERT(isShort()); + JS_ASSERT(JSString::isShort()); } inline void JSAtom::finalize(JSRuntime *rt) { - JS_ASSERT(isAtom()); + JS_ASSERT(JSString::isAtom()); if (getAllocKind() == js::gc::FINALIZE_STRING) - asFlat().finalize(rt); + JSFlatString::finalize(rt); else JS_ASSERT(getAllocKind() == js::gc::FINALIZE_SHORT_STRING); } diff --git a/js/src/vm/String.cpp b/js/src/vm/String.cpp index a26f2fe77c4..19ecd82e5f2 100644 --- a/js/src/vm/String.cpp +++ b/js/src/vm/String.cpp @@ -295,7 +295,7 @@ js_ConcatStrings(JSContext *cx, JSString *left, JSString *right) JSFixedString * JSDependentString::undepend(JSContext *cx) { - JS_ASSERT(isDependent()); + JS_ASSERT(JSString::isDependent()); size_t n = length(); size_t size = (n + 1) * sizeof(jschar); diff --git a/js/src/vm/String.h b/js/src/vm/String.h index 5a58e7f5f18..ae7dc7957b0 100644 --- a/js/src/vm/String.h +++ b/js/src/vm/String.h @@ -319,7 +319,7 @@ class JSString : public js::gc::Cell } JS_ALWAYS_INLINE - JSRope &asRope() { + JSRope &asRope() const { JS_ASSERT(isRope()); return *(JSRope *)this; } @@ -330,8 +330,8 @@ class JSString : public js::gc::Cell } JS_ALWAYS_INLINE - JSLinearString &asLinear() { - JS_ASSERT(isLinear()); + JSLinearString &asLinear() const { + JS_ASSERT(JSString::isLinear()); return *(JSLinearString *)this; } @@ -343,7 +343,7 @@ class JSString : public js::gc::Cell } JS_ALWAYS_INLINE - JSDependentString &asDependent() { + JSDependentString &asDependent() const { JS_ASSERT(isDependent()); return *(JSDependentString *)this; } @@ -354,7 +354,7 @@ class JSString : public js::gc::Cell } JS_ALWAYS_INLINE - JSFlatString &asFlat() { + JSFlatString &asFlat() const { JS_ASSERT(isFlat()); return *(JSFlatString *)this; } @@ -376,7 +376,7 @@ class JSString : public js::gc::Cell bool isInline() const; JS_ALWAYS_INLINE - JSFixedString &asFixed() { + JSFixedString &asFixed() const { JS_ASSERT(isFixed()); return *(JSFixedString *)this; } @@ -384,7 +384,7 @@ class JSString : public js::gc::Cell bool isExternal() const; JS_ALWAYS_INLINE - JSExternalString &asExternal() { + JSExternalString &asExternal() const { JS_ASSERT(isExternal()); return *(JSExternalString *)this; } @@ -449,12 +449,17 @@ class JSLinearString : public JSString { friend class JSString; + /* Vacuous and therefore unimplemented. */ + JSLinearString *ensureLinear(JSContext *cx); + bool isLinear() const; + JSLinearString &asLinear() const; + public: void mark(JSTracer *trc); JS_ALWAYS_INLINE const jschar *chars() const { - JS_ASSERT(isLinear()); + JS_ASSERT(JSString::isLinear()); return d.u1.chars; } }; @@ -468,12 +473,16 @@ class JSDependentString : public JSLinearString void init(JSLinearString *base, const jschar *chars, size_t length); + /* Vacuous and therefore unimplemented. */ + bool isDependent() const; + JSDependentString &asDependent() const; + public: static inline JSDependentString *new_(JSContext *cx, JSLinearString *base, const jschar *chars, size_t length); JSLinearString *base() const { - JS_ASSERT(isDependent()); + JS_ASSERT(JSString::isDependent()); return d.s.u2.base; } }; @@ -488,10 +497,15 @@ class JSFlatString : public JSLinearString d.s.u2.base = base; } + /* Vacuous and therefore unimplemented. */ + JSFlatString *ensureFlat(JSContext *cx); + bool isFlat() const; + JSFlatString &asFlat() const; + public: JS_ALWAYS_INLINE const jschar *charsZ() const { - JS_ASSERT(isFlat()); + JS_ASSERT(JSString::isFlat()); return chars(); } @@ -519,10 +533,14 @@ JS_STATIC_ASSERT(sizeof(JSFlatString) == sizeof(JSString)); class JSExtensibleString : public JSFlatString { + /* Vacuous and therefore unimplemented. */ + bool isExtensible() const; + JSExtensibleString &asExtensible() const; + public: JS_ALWAYS_INLINE size_t capacity() const { - JS_ASSERT(isExtensible()); + JS_ASSERT(JSString::isExtensible()); return d.s.u2.capacity; } }; @@ -533,6 +551,11 @@ class JSFixedString : public JSFlatString { void init(const jschar *chars, size_t length); + /* Vacuous and therefore unimplemented. */ + JSFlatString *ensureFixed(JSContext *cx); + bool isFixed() const; + JSFixedString &asFixed() const; + public: static inline JSFixedString *new_(JSContext *cx, const jschar *chars, size_t length); @@ -615,18 +638,22 @@ class JSExternalString : public JSFixedString void init(const jschar *chars, size_t length, intN type, void *closure); + /* Vacuous and therefore unimplemented. */ + bool isExternal() const; + JSExternalString &asExternal() const; + public: static inline JSExternalString *new_(JSContext *cx, const jschar *chars, size_t length, intN type, void *closure); intN externalType() const { - JS_ASSERT(isExternal()); + JS_ASSERT(JSString::isExternal()); JS_ASSERT(d.s.u2.externalType < TYPE_LIMIT); return intN(d.s.u2.externalType); } void *externalClosure() const { - JS_ASSERT(isExternal()); + JS_ASSERT(JSString::isExternal()); return d.s.u3.externalClosure; } @@ -654,6 +681,10 @@ JS_STATIC_ASSERT(sizeof(JSExternalString) == sizeof(JSString)); class JSAtom : public JSFixedString { + /* Vacuous and therefore unimplemented. */ + bool isAtom() const; + JSAtom &asAtom() const; + public: /* Returns the PropertyName for this. isIndex() must be false. */ inline js::PropertyName *asPropertyName();