diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-08-08 21:33:18 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-08-15 14:24:41 +0000 |
commit | b862d429b1010fecf2e29d0e781b012a4b07cad6 (patch) | |
tree | d0040a21dd8d55cbf42f9724e67f2deb3e470b41 /src | |
parent | 4bfd94c35e5099557cafcc9ae9b7d7a970089c9f (diff) |
Fix some details in RegExp handling
Change-Id: If9f7c07ea657ba8503b9188a7b77e301f23423ef
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexp_p.h | 17 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject.cpp | 37 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4regexpobject_p.h | 9 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4stringobject.cpp | 5 |
5 files changed, 52 insertions, 18 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 444d12d118..5db26857e4 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -374,7 +374,7 @@ ExecutionEngine::ExecutionEngine(QJSEngine *jsEngine) ic = newInternalClass(QV4::RegExpObject::staticVTable(), objectPrototype()); ic = ic->addMember(id_lastIndex()->propertyKey(), Attr_NotEnumerable|Attr_NotConfigurable, &index); Q_ASSERT(index == RegExpObject::Index_LastIndex); - jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(ic->d()); + jsObjects[RegExpProto] = memoryManager->allocObject<RegExpPrototype>(classes[Class_Object]); classes[Class_RegExpObject] = ic->changePrototype(regExpPrototype()->d()); ic = classes[Class_ArrayObject]->addMember(id_index()->propertyKey(), Attr_Data, &index); diff --git a/src/qml/jsruntime/qv4regexp_p.h b/src/qml/jsruntime/qv4regexp_p.h index b027ba7659..6afb10ea95 100644 --- a/src/qml/jsruntime/qv4regexp_p.h +++ b/src/qml/jsruntime/qv4regexp_p.h @@ -91,6 +91,13 @@ struct RegExp : Base { return false; #endif } + + bool ignoreCase() const { return flags & CompiledData::RegExp::RegExp_IgnoreCase; } + bool multiLine() const { return flags & CompiledData::RegExp::RegExp_Multiline; } + bool global() const { return flags & CompiledData::RegExp::RegExp_Global; } + bool unicode() const { return flags & CompiledData::RegExp::RegExp_Unicode; } + bool sticky() const { return flags & CompiledData::RegExp::RegExp_Sticky; } + RegExpCache *cache; int subPatternCount; uint flags; @@ -117,11 +124,11 @@ struct RegExp : public Managed #endif RegExpCache *cache() const { return d()->cache; } int subPatternCount() const { return d()->subPatternCount; } - bool ignoreCase() const { return d()->flags & CompiledData::RegExp::RegExp_IgnoreCase; } - bool multiLine() const { return d()->flags & CompiledData::RegExp::RegExp_Multiline; } - bool global() const { return d()->flags & CompiledData::RegExp::RegExp_Global; } - bool unicode() const { return d()->flags & CompiledData::RegExp::RegExp_Unicode; } - bool sticky() const { return d()->flags & CompiledData::RegExp::RegExp_Sticky; } + bool ignoreCase() const { return d()->ignoreCase(); } + bool multiLine() const { return d()->multiLine(); } + bool global() const { return d()->global(); } + bool unicode() const { return d()->unicode(); } + bool sticky() const { return d()->sticky(); } static Heap::RegExp *create(ExecutionEngine* engine, const QString& pattern, uint flags = CompiledData::RegExp::RegExp_NoFlags); diff --git a/src/qml/jsruntime/qv4regexpobject.cpp b/src/qml/jsruntime/qv4regexpobject.cpp index d157350e00..0acefc26d2 100644 --- a/src/qml/jsruntime/qv4regexpobject.cpp +++ b/src/qml/jsruntime/qv4regexpobject.cpp @@ -180,7 +180,7 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s QString s = str->toQString(); Scope scope(engine); - int offset = global() ? lastIndex() : 0; + int offset = (global() || sticky()) ? lastIndex() : 0; if (offset < 0 || offset > s.length()) { setLastIndex(0); RETURN_RESULT(Encode::null()); @@ -193,7 +193,8 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s regExpCtor->d()->clearLastMatch(); if (result == -1) { - setLastIndex(0); + if (global() || sticky()) + setLastIndex(0); RETURN_RESULT(Encode::null()); } @@ -221,7 +222,7 @@ ReturnedValue RegExpObject::builtinExec(ExecutionEngine *engine, const String *s dd->lastMatchStart = matchOffsets[0]; dd->lastMatchEnd = matchOffsets[1]; - if (global()) + if (global() || sticky()) setLastIndex(matchOffsets[1]); return array.asReturnedValue(); @@ -473,8 +474,11 @@ ReturnedValue RegExpPrototype::method_get_global(const FunctionObject *f, const { Scope scope(f); Scoped<RegExpObject> re(scope, thisObject); - if (!re) + if (!re) { + if (thisObject->sameValue(*scope.engine->regExpPrototype())) + return Encode::undefined(); return scope.engine->throwTypeError(); + } bool b = re->value()->flags & CompiledData::RegExp::RegExp_Global; return Encode(b); @@ -484,8 +488,11 @@ ReturnedValue RegExpPrototype::method_get_ignoreCase(const FunctionObject *f, co { Scope scope(f); Scoped<RegExpObject> re(scope, thisObject); - if (!re) + if (!re) { + if (thisObject->sameValue(*scope.engine->regExpPrototype())) + return Encode::undefined(); return scope.engine->throwTypeError(); + } bool b = re->value()->flags & CompiledData::RegExp::RegExp_IgnoreCase; return Encode(b); @@ -557,8 +564,11 @@ ReturnedValue RegExpPrototype::method_get_multiline(const FunctionObject *f, con { Scope scope(f); Scoped<RegExpObject> re(scope, thisObject); - if (!re) + if (!re) { + if (thisObject->sameValue(*scope.engine->regExpPrototype())) + return Encode::undefined(); return scope.engine->throwTypeError(); + } bool b = re->value()->flags & CompiledData::RegExp::RegExp_Multiline; return Encode(b); @@ -705,8 +715,11 @@ ReturnedValue RegExpPrototype::method_get_source(const FunctionObject *f, const { Scope scope(f); Scoped<RegExpObject> re(scope, thisObject); - if (!re) + if (!re) { + if (thisObject->sameValue(*scope.engine->regExpPrototype())) + return scope.engine->newString(QStringLiteral("(?:)"))->asReturnedValue(); return scope.engine->throwTypeError(); + } return scope.engine->newString(re->toString())->asReturnedValue(); } @@ -715,8 +728,11 @@ ReturnedValue RegExpPrototype::method_get_sticky(const FunctionObject *f, const { Scope scope(f); Scoped<RegExpObject> re(scope, thisObject); - if (!re) + if (!re) { + if (thisObject->sameValue(*scope.engine->regExpPrototype())) + return Encode::undefined(); return scope.engine->throwTypeError(); + } bool b = re->value()->flags & CompiledData::RegExp::RegExp_Sticky; return Encode(b); @@ -754,8 +770,11 @@ ReturnedValue RegExpPrototype::method_get_unicode(const FunctionObject *f, const { Scope scope(f); Scoped<RegExpObject> re(scope, thisObject); - if (!re) + if (!re) { + if (thisObject->sameValue(*scope.engine->regExpPrototype())) + return Encode::undefined(); return scope.engine->throwTypeError(); + } bool b = re->value()->flags & CompiledData::RegExp::RegExp_Unicode; return Encode(b); diff --git a/src/qml/jsruntime/qv4regexpobject_p.h b/src/qml/jsruntime/qv4regexpobject_p.h index 2173981b66..ba5a106c6b 100644 --- a/src/qml/jsruntime/qv4regexpobject_p.h +++ b/src/qml/jsruntime/qv4regexpobject_p.h @@ -122,7 +122,8 @@ struct RegExpObject: Object { enum { NInlineProperties = 5 }; Heap::RegExp *value() const { return d()->value; } - bool global() const { return d()->value->flags & CompiledData::RegExp::RegExp_Global; } + bool global() const { return d()->value->global(); } + bool sticky() const { return d()->value->sticky(); } void initProperties(); @@ -132,6 +133,10 @@ struct RegExpObject: Object { } void setLastIndex(int index) { Q_ASSERT(Index_LastIndex == internalClass()->find(engine()->id_lastIndex()->propertyKey())); + if (!internalClass()->propertyData[Index_LastIndex].isWritable()) { + engine()->throwTypeError(); + return; + } return setProperty(Index_LastIndex, Primitive::fromInt32(index)); } @@ -156,7 +161,7 @@ struct RegExpCtor: FunctionObject static ReturnedValue virtualCall(const FunctionObject *f, const Value *thisObject, const Value *argv, int argc); }; -struct RegExpPrototype: RegExpObject +struct RegExpPrototype: Object { void init(ExecutionEngine *engine, Object *ctor); diff --git a/src/qml/jsruntime/qv4stringobject.cpp b/src/qml/jsruntime/qv4stringobject.cpp index de8fa0c2ee..e13accd4ea 100644 --- a/src/qml/jsruntime/qv4stringobject.cpp +++ b/src/qml/jsruntime/qv4stringobject.cpp @@ -799,8 +799,11 @@ ReturnedValue StringPrototype::method_replace(const FunctionObject *b, const Val break; offset = qMax(offset + 1, matchOffsets[oldSize + 1]); } - if (regExp->global()) + if (regExp->global()) { regExp->setLastIndex(0); + if (scope.hasException()) + return Encode::undefined(); + } numStringMatches = nMatchOffsets / (regExp->value()->captureCount() * 2); numCaptures = regExp->value()->captureCount(); } else { |