Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: mozilla/rhino
...
head fork: mozilla/rhino
Checking mergeability… Don't worry, you can still create the pull request.
  • 2 commits
  • 4 files changed
  • 0 commit comments
  • 1 contributor
Commits on May 24, 2012
@hns hns Undo some recent changes in RECompiled
 - Do not store source string
 - Remove unused methods
20c659b
@hns hns Make sure slashes in RegExp source/toString() are escaped.
Fixes bug #510265 except for the source property of empty regexp
where we follow Spidermonkey/V8.
06e155e
View
56 src/org/mozilla/javascript/regexp/NativeRegExp.java
@@ -171,9 +171,9 @@ public static void init(Context cx, Scriptable scope, boolean sealed)
defineProperty(scope, "RegExp", ctor, ScriptableObject.DONTENUM);
}
- NativeRegExp(Scriptable scope, Object regexpCompiled)
+ NativeRegExp(Scriptable scope, RECompiled regexpCompiled)
{
- this.re = (RECompiled)regexpCompiled;
+ this.re = regexpCompiled;
this.lastIndex = 0;
ScriptRuntime.setBuiltinProtoAndParent(this, scope, TopLevel.Builtins.RegExp);
}
@@ -218,7 +218,7 @@ Scriptable compile(Context cx, Scriptable scope, Object[] args)
this.lastIndex = thatObj.lastIndex;
return this;
}
- String s = args.length == 0 ? "" : ScriptRuntime.toString(args[0]);
+ String s = args.length == 0 ? "" : escapeRegExp(args[0]);
String global = args.length > 1 && args[1] != Undefined.instance
? ScriptRuntime.toString(args[1])
: null;
@@ -230,7 +230,7 @@ Scriptable compile(Context cx, Scriptable scope, Object[] args)
@Override
public String toString()
{
- StringBuffer buf = new StringBuffer();
+ StringBuilder buf = new StringBuilder();
buf.append('/');
if (re.source.length != 0) {
buf.append(re.source);
@@ -255,6 +255,30 @@ private static RegExpImpl getImpl(Context cx)
return (RegExpImpl) ScriptRuntime.getRegExpProxy(cx);
}
+ private static String escapeRegExp(Object src) {
+ String s = ScriptRuntime.toString(src);
+ // Escape any naked slashes in regexp source, see bug #510265
+ StringBuilder sb = null; // instantiated only if necessary
+ int start = 0;
+ int slash = s.indexOf('/');
+ while (slash > -1) {
+ if (slash == start || s.charAt(slash - 1) != '\\') {
+ if (sb == null) {
+ sb = new StringBuilder();
+ }
+ sb.append(s, start, slash);
+ sb.append("\\/");
+ start = slash + 1;
+ }
+ slash = s.indexOf('/', slash + 1);
+ }
+ if (sb != null) {
+ sb.append(s, start, s.length());
+ s = sb.toString();
+ }
+ return s;
+ }
+
private Object execSub(Context cx, Scriptable scopeObj,
Object[] args, int matchType)
{
@@ -1391,11 +1415,13 @@ private static int getIndex(byte[] array, int pc)
{
if ((gData.cp + length) > end)
return false;
- if (input.regionMatches(gData.cp, gData.regexp.sourceString, matchChars, length)) {
- gData.cp += length;
- return true;
+ for (int i = 0; i < length; i++) {
+ if (gData.regexp.source[matchChars + i] != input.charAt(gData.cp + i)) {
+ return false;
+ }
}
- return false;
+ gData.cp += length;
+ return true;
}
private static boolean
@@ -2758,7 +2784,6 @@ protected int findPrototypeId(String s)
static final long serialVersionUID = -6144956577595844213L;
final char[] source; /* locked source string, sans // */
- final String sourceString;
int parenCount; /* number of parenthesized submatches */
int flags; /* flags */
byte[] program; /* regular expression bytecode */
@@ -2767,21 +2792,8 @@ protected int findPrototypeId(String s)
int anchorCh = -1; /* if >= 0, then re starts with this literal char */
RECompiled(String str) {
- this.sourceString = str;
this.source = str.toCharArray();
}
-
- public int flags() {
- return flags;
- }
-
- public String source() {
- return sourceString;
- }
-
- public int parenCount() {
- return parenCount;
- }
}
class RENode {
View
6 src/org/mozilla/javascript/regexp/RegExpImpl.java
@@ -56,7 +56,7 @@ public Object compileRegExp(Context cx, String source, String flags)
public Scriptable wrapRegExp(Context cx, Scriptable scope,
Object compiled)
{
- return new NativeRegExp(scope, compiled);
+ return new NativeRegExp(scope, (RECompiled) compiled);
}
public Object action(Context cx, Scriptable scope,
@@ -136,7 +136,7 @@ private static Object matchOrReplace(Context cx, Scriptable scope,
Scriptable topScope = ScriptableObject.getTopLevelScope(scope);
if (args.length == 0) {
- Object compiled = NativeRegExp.compileRE(cx, "", "", false);
+ RECompiled compiled = NativeRegExp.compileRE(cx, "", "", false);
re = new NativeRegExp(topScope, compiled);
} else if (args[0] instanceof NativeRegExp) {
re = (NativeRegExp) args[0];
@@ -149,7 +149,7 @@ private static Object matchOrReplace(Context cx, Scriptable scope,
} else {
opt = null;
}
- Object compiled = NativeRegExp.compileRE(cx, src, opt, forceFlat);
+ RECompiled compiled = NativeRegExp.compileRE(cx, src, opt, forceFlat);
re = new NativeRegExp(topScope, compiled);
}
View
0  testsrc/doctests/regexp-literals.doctest → testsrc/doctests/regexp.literals.doctest
File renamed without changes
View
90 testsrc/doctests/regexp.source.doctest
@@ -0,0 +1,90 @@
+js> x = RegExp('')
+/(?:)/
+js> x.source
+
+js> RegExp('a').source
+a
+js> RegExp('\\\\').source
+\\
+js> RegExp('\\\\\\\\').source
+\\\\
+js> x = RegExp('/')
+/\//
+js> x.source
+\/
+js> x.test('/')
+true
+js> x = RegExp('//')
+/\/\//
+js> x.source
+\/\/
+js> x.test('//')
+true
+js> x = RegExp('\/')
+/\//
+js> x.source
+\/
+js> x.test('/')
+true
+js> x = RegExp('\\/')
+/\//
+js> x.source
+\/
+js> x.test('/')
+true
+js> x = RegExp('\\\/')
+/\//
+js> x.source
+\/
+js> x.test('/')
+true
+js> x = RegExp('\\\\/')
+/\\//
+js> x.source
+\\/
+js> x.test('/')
+false
+js> x.test('\\/')
+true
+js> x = RegExp('/abc\/foo\\/bar\\\/xyz/')
+/\/abc\/foo\/bar\/xyz\//
+js> x.source
+\/abc\/foo\/bar\/xyz\/
+js> x.test('/abc/foo/bar/xyz/')
+true
+js> RegExp('[^/]*')
+/[^\/]*/
+js> RegExp('[^\/]*')
+/[^\/]*/
+js> RegExp('[^\\/]*')
+/[^\/]*/
+
+js> /./.compile('')
+/(?:)/
+js> /./.compile('a')
+/a/
+js> /./.compile('\\\\')
+/\\/
+js> /./.compile('\\\\\\\\')
+/\\\\/
+js> /./.compile('/')
+/\//
+js> /./.compile('//')
+/\/\//
+js> /./.compile('\/')
+/\//
+js> /./.compile('\\/')
+/\//
+js> /./.compile('\\\/')
+/\//
+js> /./.compile('\\\\/')
+/\\//
+js> /./.compile('/abc\/foo\\/bar\\\/xyz/')
+/\/abc\/foo\/bar\/xyz\//
+js> /./.compile('[^/]*')
+/[^\/]*/
+js> /./.compile('[^\/]*')
+/[^\/]*/
+js> /./.compile('[^\\/]*')
+/[^\/]*/
+

No commit comments for this range

Something went wrong with that request. Please try again.