Summary: | method compile for regexp class doesn't exist in KJS | ||
---|---|---|---|
Product: | [Applications] konqueror | Reporter: | Sergio Cambra <sergio> |
Component: | kjs | Assignee: | Konqueror Developers <konq-bugs> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | maksim, paranoid_ |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Ubuntu | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: | ||
Sentry Crash Report: |
Description
Sergio Cambra
2006-01-14 16:41:06 UTC
*** Bug 122469 has been marked as a duplicate of this bug. *** SVN commit 513944 by orlovich: - Support .compile on regexpen (#120108) - Error out if flags are invalid - Don't leak RegExp objects on errors. Reviewed by Harri BUG: 120108 M +75 -28 regexp_object.cpp M +9 -2 regexp_object.h --- branches/KDE/3.5/kdelibs/kjs/regexp_object.cpp #513943:513944 @@ -59,6 +59,9 @@ new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Test, 0, testPropertyName), DontEnum); putDirect(toStringPropertyName, new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::ToString, 0, toStringPropertyName), DontEnum); + static const Identifier compilePropertyName("compile"); + putDirect(compilePropertyName, + new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Compile, 1, compilePropertyName), DontEnum); } // ------------------------------ RegExpProtoFuncImp --------------------------- @@ -152,7 +155,15 @@ str += "m"; } return String(str); + case Compile: { + RegExp* newEngine = RegExpObjectImp::makeEngine(exec, args[0].toString(exec), args[1]); + if (!newEngine) + return exec->exception(); + reimp->setRegExp(newEngine); + return Value(reimp); + } } + return Undefined(); } @@ -171,6 +182,23 @@ delete reg; } +void RegExpImp::setRegExp(RegExp *r) +{ + delete reg; + reg = r; + + Object protect(this);//Protect self from GC (we are allocating a StringImp, and may be new) + putDirect("global", (r->flags() & RegExp::Global) ? BooleanImp::staticTrue : BooleanImp::staticFalse, + DontDelete | ReadOnly | DontEnum); + putDirect("ignoreCase", (r->flags() & RegExp::IgnoreCase) ? BooleanImp::staticTrue : BooleanImp::staticFalse, + DontDelete | ReadOnly | DontEnum); + putDirect("multiline", (r->flags() & RegExp::Multiline) ? BooleanImp::staticTrue : BooleanImp::staticFalse, + DontDelete | ReadOnly | DontEnum); + + putDirect("source", new StringImp(r->pattern()), DontDelete | ReadOnly | DontEnum); + putDirect("lastIndex", NumberImp::zero(), DontDelete | DontEnum); +} + // ------------------------------ RegExpObjectImp ------------------------------ RegExpObjectImp::RegExpObjectImp(ExecState * /*exec*/, @@ -243,6 +271,49 @@ return true; } +RegExp* RegExpObjectImp::makeEngine(ExecState *exec, const UString &p, const Value &flagsInput) +{ + UString flags = flagsInput.type() == UndefinedType ? UString("") : flagsInput.toString(exec); + + // Check for validity of flags + for (int pos = 0; pos < flags.size(); ++pos) { + switch (flags[pos].unicode()) { + case 'g': + case 'i': + case 'm': + break; + default: { + Object err = Error::create(exec, SyntaxError, + "Invalid regular expression flags"); + exec->setException(err); + return 0; + } + } + } + + bool global = (flags.find("g") >= 0); + bool ignoreCase = (flags.find("i") >= 0); + bool multiline = (flags.find("m") >= 0); + + int reflags = RegExp::None; + if (global) + reflags |= RegExp::Global; + if (ignoreCase) + reflags |= RegExp::IgnoreCase; + if (multiline) + reflags |= RegExp::Multiline; + + RegExp *re = new RegExp(p, reflags); + if (!re->isValid()) { + Object err = Error::create(exec, SyntaxError, + "Invalid regular expression"); + exec->setException(err); + delete re; + return 0; + } + return re; +} + // ECMA 15.10.4 Object RegExpObjectImp::construct(ExecState *exec, const List &args) { @@ -264,38 +335,14 @@ p = a0.toString(exec); } } - UString flags = args[1].type() == UndefinedType ? UString("") : args[1].toString(exec); + RegExp* re = makeEngine(exec, p, args[1]); + if (!re) + return exec->exception().toObject(exec); + RegExpPrototypeImp *proto = static_cast<RegExpPrototypeImp*>(exec->lexicalInterpreter()->builtinRegExpPrototype().imp()); RegExpImp *dat = new RegExpImp(proto); Object obj(dat); // protect from GC - - bool global = (flags.find("g") >= 0); - bool ignoreCase = (flags.find("i") >= 0); - bool multiline = (flags.find("m") >= 0); - // TODO: throw a syntax error on invalid flags - - dat->putDirect("global", global ? BooleanImp::staticTrue : BooleanImp::staticFalse, DontDelete | ReadOnly | DontEnum); - dat->putDirect("ignoreCase", ignoreCase ? BooleanImp::staticTrue : BooleanImp::staticFalse, DontDelete | ReadOnly | DontEnum); - dat->putDirect("multiline", multiline ? BooleanImp::staticTrue : BooleanImp::staticFalse, DontDelete | ReadOnly | DontEnum); - - dat->putDirect("source", new StringImp(p), DontDelete | ReadOnly | DontEnum); - dat->putDirect("lastIndex", NumberImp::zero(), DontDelete | DontEnum); - - int reflags = RegExp::None; - if (global) - reflags |= RegExp::Global; - if (ignoreCase) - reflags |= RegExp::IgnoreCase; - if (multiline) - reflags |= RegExp::Multiline; - RegExp *re = new RegExp(p, reflags); - if (!re->isValid()) { - Object err = Error::create(exec, SyntaxError, - "Invalid regular expression"); - exec->setException(err); - return err; - } dat->setRegExp(re); return obj; --- branches/KDE/3.5/kdelibs/kjs/regexp_object.h #513943:513944 @@ -45,7 +45,7 @@ virtual bool implementsCall() const; virtual Value call(ExecState *exec, Object &thisObj, const List &args); - enum { Exec, Test, ToString }; + enum { Exec, Test, ToString, Compile }; private: int id; }; @@ -54,7 +54,7 @@ public: RegExpImp(RegExpPrototypeImp *regexpProto); ~RegExpImp(); - void setRegExp(RegExp *r) { reg = r; } + void setRegExp(RegExp *r); RegExp* regExp() { return reg; } virtual const ClassInfo *classInfo() const { return &info; } @@ -78,6 +78,13 @@ int ** registerRegexp( const RegExp* re, const UString& s ); void setSubPatterns(int num) { lastNrSubPatterns = num; } Object arrayOfMatches(ExecState *exec, const UString &result) const; + + /* + Attempts to create a new regular expression engine for the string p + and the flags stored in flagsInput. If this succeeds, it returns the + engine. If not, it returns 0, and raises an exception in exec + */ + static RegExp* makeEngine(ExecState *exec, const UString &p, const Value &flagsInput); private: UString lastString; int *lastOvector; SVN commit 513946 by orlovich: Testcase for #120108. And now back to grading.. CCBUG:120108 A baseline/js/regexp-compile.html-dom AM baseline/js/regexp-compile.html-dump.png A baseline/js/regexp-compile.html-render A tests/js/regexp-compile.html ** trunk/tests/khtmltests/regression/baseline/js/regexp-compile.html-dump.png #property svn:mime-type + application/octet-stream |