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 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)); + } }