diff --git a/README.html b/README.html
index 031bbd28..4e4a189c 100644
--- a/README.html
+++ b/README.html
@@ -917,6 +917,9 @@ Files are no longer hosted at LuaForge.
| 3.0-beta3 |
- Fix maven sample code.
+- Add sample code for Android Application that uses luaj.
+- Add sample code for Applet that uses luaj.
+- Fix balanced match for empty string (fixes issue #23).
|
diff --git a/src/core/org/luaj/vm2/LuaString.java b/src/core/org/luaj/vm2/LuaString.java
index 6bac4180..fbd9a08a 100644
--- a/src/core/org/luaj/vm2/LuaString.java
+++ b/src/core/org/luaj/vm2/LuaString.java
@@ -387,6 +387,12 @@ public class LuaString extends LuaValue {
return this;
}
+ /** Take a substring using Java zero-based indexes for begin and end or range.
+ * @param beginIndex The zero-based index of the first character to include.
+ * @param endIndex The zero-based index of position after the last character.
+ * @return LuaString which is a substring whose first character is at offset
+ * beginIndex and extending for (endIndex - beginIndex ) characters.
+ */
public LuaString substring( int beginIndex, int endIndex ) {
return valueOf( m_bytes, m_offset + beginIndex, endIndex - beginIndex );
}
diff --git a/src/core/org/luaj/vm2/lib/StringLib.java b/src/core/org/luaj/vm2/lib/StringLib.java
index 756d69b2..f92a99b5 100644
--- a/src/core/org/luaj/vm2/lib/StringLib.java
+++ b/src/core/org/luaj/vm2/lib/StringLib.java
@@ -1155,18 +1155,19 @@ public class StringLib extends TwoArgFunction {
if ( poff == plen || poff + 1 == plen ) {
error( "unbalanced pattern" );
}
- if ( s.luaByte( soff ) != p.luaByte( poff ) )
+ final int slen = s.length();
+ if ( soff >= slen )
return -1;
- else {
- int b = p.luaByte( poff );
- int e = p.luaByte( poff + 1 );
- int cont = 1;
- while ( ++soff < s.length() ) {
- if ( s.luaByte( soff ) == e ) {
- if ( --cont == 0 ) return soff + 1;
- }
- else if ( s.luaByte( soff ) == b ) cont++;
+ final int b = p.luaByte( poff );
+ if ( s.luaByte( soff ) != b )
+ return -1;
+ final int e = p.luaByte( poff + 1 );
+ int cont = 1;
+ while ( ++soff < slen ) {
+ if ( s.luaByte( soff ) == e ) {
+ if ( --cont == 0 ) return soff + 1;
}
+ else if ( s.luaByte( soff ) == b ) cont++;
}
return -1;
}
diff --git a/test/junit/org/luaj/vm2/StringTest.java b/test/junit/org/luaj/vm2/StringTest.java
index b084bf22..ff01d0d6 100644
--- a/test/junit/org/luaj/vm2/StringTest.java
+++ b/test/junit/org/luaj/vm2/StringTest.java
@@ -349,4 +349,33 @@ public class StringTest extends TestCase {
assertEquals(1, sub.indexOfAny(CdEFGHIJ));
assertEquals(-1, sub.indexOfAny(EFGHIJKL));
}
+
+ public void testMatchShortPatterns() {
+ LuaValue[] args = { LuaString.valueOf("%bxy") };
+ LuaString _ = LuaString.valueOf("");
+
+ LuaString a = LuaString.valueOf("a");
+ LuaString ax = LuaString.valueOf("ax");
+ LuaString axb = LuaString.valueOf("axb");
+ LuaString axby = LuaString.valueOf("axby");
+ LuaString xbya = LuaString.valueOf("xbya");
+ LuaString bya = LuaString.valueOf("bya");
+ LuaString xby = LuaString.valueOf("xby");
+ LuaString axbya = LuaString.valueOf("axbya");
+ LuaValue nil = LuaValue.NIL;
+
+ assertEquals(nil, _.invokemethod("match", args));
+ assertEquals(nil, a.invokemethod("match", args));
+ assertEquals(nil, ax.invokemethod("match", args));
+ assertEquals(nil, axb.invokemethod("match", args));
+ assertEquals(xby, axby.invokemethod("match", args));
+ assertEquals(xby, xbya.invokemethod("match", args));
+ assertEquals(nil, bya.invokemethod("match", args));
+ assertEquals(xby, xby.invokemethod("match", args));
+ assertEquals(xby, axbya.invokemethod("match", args));
+ assertEquals(xby, axbya.substring(0,4).invokemethod("match", args));
+ assertEquals(nil, axbya.substring(0,3).invokemethod("match", args));
+ assertEquals(xby, axbya.substring(1,5).invokemethod("match", args));
+ assertEquals(nil, axbya.substring(2,5).invokemethod("match", args));
+ }
}