| Summary: | method compile for regexp class doesn't exist in KJS | ||
|---|---|---|---|
| Product: | [Applications] konqueror | Reporter: | Sergio Cambra <sergio> | 
| Component: | kjs | Assignee: | Konqueror Bugs <konqueror-bugs-null> | 
| Status: | RESOLVED FIXED | ||
| Severity: | normal | CC: | maksim, paranoid_ | 
| Priority: | NOR | ||
| Version First Reported In: | unspecified | ||
| Target Milestone: | --- | ||
| Platform: | Ubuntu | ||
| OS: | Linux | ||
| Latest Commit: | Version Fixed/Implemented 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 |