Improve argument type checkign on string libraries.
This commit is contained in:
@@ -26,6 +26,7 @@ import org.luaj.vm.LNumber;
|
|||||||
import org.luaj.vm.LString;
|
import org.luaj.vm.LString;
|
||||||
import org.luaj.vm.LTable;
|
import org.luaj.vm.LTable;
|
||||||
import org.luaj.vm.LValue;
|
import org.luaj.vm.LValue;
|
||||||
|
import org.luaj.vm.Lua;
|
||||||
import org.luaj.vm.LuaState;
|
import org.luaj.vm.LuaState;
|
||||||
|
|
||||||
|
|
||||||
@@ -152,21 +153,21 @@ public class StringLib extends LFunction {
|
|||||||
* @param vm the calling vm
|
* @param vm the calling vm
|
||||||
*/
|
*/
|
||||||
static void byte_( LuaState vm ) {
|
static void byte_( LuaState vm ) {
|
||||||
LString ls = vm.tolstring(2);
|
LString s = vm.checklstring(2);
|
||||||
int l = ls.length();
|
int l = s.m_length;
|
||||||
final int top = vm.gettop();
|
int posi = posrelat( vm.optint(3,1), l );
|
||||||
int i = posrelat( ( top >= 3 ) ? vm.tointeger(3) : 1, l );
|
int pose = posrelat( vm.optint(4,posi), l );
|
||||||
int j = posrelat( ( top >= 4 ) ? vm.tointeger(4) : i, l );
|
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
if ( i <= 0 )
|
int n,i;
|
||||||
i = 1;
|
if (posi <= 0) posi = 1;
|
||||||
if ( j > l )
|
if (pose > l) pose = l;
|
||||||
j = l;
|
if (posi > pose) return; /* empty interval; return no values */
|
||||||
if ( i > j )
|
n = (int)(pose - posi + 1);
|
||||||
return;
|
if (posi + n <= pose) /* overflow? */
|
||||||
int n = j - i + 1;
|
vm.error("string slice too long");
|
||||||
for ( int k=0; k < n; k++ )
|
vm.checkstack(n);
|
||||||
vm.pushinteger( ls.luaByte(k+i-1) );
|
for (i=0; i<n; i++)
|
||||||
|
vm.pushinteger(s.luaByte(posi+i-1));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -181,10 +182,13 @@ public class StringLib extends LFunction {
|
|||||||
* @param vm the calling VM
|
* @param vm the calling VM
|
||||||
*/
|
*/
|
||||||
public static void char_( LuaState vm) {
|
public static void char_( LuaState vm) {
|
||||||
int nargs = vm.gettop()-1;
|
int n = vm.gettop()-1;
|
||||||
byte[] bytes = new byte[nargs];
|
byte[] bytes = new byte[n];
|
||||||
for ( int i=0; i<nargs; i++ )
|
for ( int i=0, a=2; i<n; i++, a++ ) {
|
||||||
bytes[i] = (byte)( vm.tointeger(i+2) & 0x0FF );
|
int c = vm.checkint(a);
|
||||||
|
vm.argcheck((c>=0 && c<256), a, "invalid value");
|
||||||
|
bytes[i] = (byte) c;
|
||||||
|
}
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushlstring( bytes );
|
vm.pushlstring( bytes );
|
||||||
}
|
}
|
||||||
@@ -275,8 +279,8 @@ public class StringLib extends LFunction {
|
|||||||
* as this would prevent the iteration.
|
* as this would prevent the iteration.
|
||||||
*/
|
*/
|
||||||
static void gmatch( LuaState vm ) {
|
static void gmatch( LuaState vm ) {
|
||||||
LString src = vm.tolstring( 2 );
|
LString src = vm.checklstring( 2 );
|
||||||
LString pat = vm.tolstring( 3 );
|
LString pat = vm.checklstring( 3 );
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushlvalue( new GMatchAux(vm, src, pat) );
|
vm.pushlvalue( new GMatchAux(vm, src, pat) );
|
||||||
}
|
}
|
||||||
@@ -354,11 +358,11 @@ public class StringLib extends LFunction {
|
|||||||
* --> x="lua-5.1.tar.gz"
|
* --> x="lua-5.1.tar.gz"
|
||||||
*/
|
*/
|
||||||
static void gsub( LuaState vm ) {
|
static void gsub( LuaState vm ) {
|
||||||
LString src = vm.tolstring(2);
|
LString src = vm.checklstring(2);
|
||||||
final int srclen = src.length();
|
final int srclen = src.length();
|
||||||
LString p = vm.tolstring(3);
|
LString p = vm.checklstring(3);
|
||||||
LValue repl = vm.topointer( 4 );
|
LValue repl = vm.topointer( 4 );
|
||||||
int max_s = ( vm.gettop() >= 5 ? vm.tointeger( 5 ) : srclen + 1 );
|
int max_s = vm.optint( 5, srclen + 1 );
|
||||||
final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^';
|
final boolean anchor = p.length() > 0 && p.charAt( 0 ) == '^';
|
||||||
|
|
||||||
LBuffer lbuf = new LBuffer( srclen );
|
LBuffer lbuf = new LBuffer( srclen );
|
||||||
@@ -395,7 +399,7 @@ public class StringLib extends LFunction {
|
|||||||
* Embedded zeros are counted, so "a\000bc\000" has length 5.
|
* Embedded zeros are counted, so "a\000bc\000" has length 5.
|
||||||
*/
|
*/
|
||||||
static void len( LuaState vm ) {
|
static void len( LuaState vm ) {
|
||||||
int l = vm.tolstring(2).length();
|
int l = vm.checklstring(2).length();
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushinteger( l );
|
vm.pushinteger( l );
|
||||||
}
|
}
|
||||||
@@ -408,7 +412,7 @@ public class StringLib extends LFunction {
|
|||||||
* The definition of what an uppercase letter is depends on the current locale.
|
* The definition of what an uppercase letter is depends on the current locale.
|
||||||
*/
|
*/
|
||||||
static void lower( LuaState vm ) {
|
static void lower( LuaState vm ) {
|
||||||
String s = vm.tostring(2).toLowerCase();
|
String s = vm.checkstring(2).toLowerCase();
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushstring( s );
|
vm.pushstring( s );
|
||||||
}
|
}
|
||||||
@@ -432,8 +436,8 @@ public class StringLib extends LFunction {
|
|||||||
* Returns a string that is the concatenation of n copies of the string s.
|
* Returns a string that is the concatenation of n copies of the string s.
|
||||||
*/
|
*/
|
||||||
static void rep( LuaState vm ) {
|
static void rep( LuaState vm ) {
|
||||||
LString s = vm.tolstring(2);
|
LString s = vm.checklstring(2);
|
||||||
int n = vm.tointeger( 3 );
|
int n = vm.checkint( 3 );
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
if ( n >= 0 ) {
|
if ( n >= 0 ) {
|
||||||
final byte[] bytes = new byte[ s.length() * n ];
|
final byte[] bytes = new byte[ s.length() * n ];
|
||||||
@@ -451,7 +455,7 @@ public class StringLib extends LFunction {
|
|||||||
* Returns a string that is the string s reversed.
|
* Returns a string that is the string s reversed.
|
||||||
*/
|
*/
|
||||||
static void reverse( LuaState vm ) {
|
static void reverse( LuaState vm ) {
|
||||||
LString s = vm.tolstring(2);
|
LString s = vm.checklstring(2);
|
||||||
int n = s.length();
|
int n = s.length();
|
||||||
byte[] b = new byte[n];
|
byte[] b = new byte[n];
|
||||||
for ( int i=0, j=n-1; i<n; i++, j-- )
|
for ( int i=0, j=n-1; i<n; i++, j-- )
|
||||||
@@ -472,12 +476,11 @@ public class StringLib extends LFunction {
|
|||||||
* returns a suffix of s with length i.
|
* returns a suffix of s with length i.
|
||||||
*/
|
*/
|
||||||
static void sub( LuaState vm ) {
|
static void sub( LuaState vm ) {
|
||||||
final int top = vm.gettop();
|
final LString s = vm.checklstring(2);
|
||||||
final LString s = vm.tolstring(2);
|
|
||||||
final int len = s.length();
|
final int len = s.length();
|
||||||
|
|
||||||
int i = posrelat( top >= 3 ? vm.tointeger( 3 ) : 1, len );
|
int i = posrelat( vm.checkint( 3 ), len );
|
||||||
int j = posrelat( top >= 4 ? vm.tointeger( 4 ) : -1, len );
|
int j = posrelat( vm.optint( 4, -1 ), len );
|
||||||
|
|
||||||
if ( i < 1 )
|
if ( i < 1 )
|
||||||
i = 1;
|
i = 1;
|
||||||
@@ -501,7 +504,7 @@ public class StringLib extends LFunction {
|
|||||||
* The definition of what a lowercase letter is depends on the current locale.
|
* The definition of what a lowercase letter is depends on the current locale.
|
||||||
*/
|
*/
|
||||||
static void upper( LuaState vm ) {
|
static void upper( LuaState vm ) {
|
||||||
String s = vm.tostring(2).toUpperCase();
|
String s = vm.checkstring(2).toUpperCase();
|
||||||
vm.resettop();
|
vm.resettop();
|
||||||
vm.pushstring(s);
|
vm.pushstring(s);
|
||||||
}
|
}
|
||||||
@@ -510,9 +513,9 @@ public class StringLib extends LFunction {
|
|||||||
* This utility method implements both string.find and string.match.
|
* This utility method implements both string.find and string.match.
|
||||||
*/
|
*/
|
||||||
static void str_find_aux( LuaState vm, boolean find ) {
|
static void str_find_aux( LuaState vm, boolean find ) {
|
||||||
LString s = vm.tolstring(2);
|
LString s = vm.checklstring(2);
|
||||||
LString pat = vm.tolstring(3);
|
LString pat = vm.checklstring(3);
|
||||||
int init = vm.gettop() >= 4 ? vm.tointeger( 4 ) : 1;
|
int init = vm.optint( 4 , 1 );
|
||||||
|
|
||||||
if ( init > 0 ) {
|
if ( init > 0 ) {
|
||||||
init = Math.min( init - 1, s.length() );
|
init = Math.min( init - 1, s.length() );
|
||||||
@@ -669,7 +672,7 @@ public class StringLib extends LFunction {
|
|||||||
vm.pop( 1 );
|
vm.pop( 1 );
|
||||||
vm.pushlvalue( ((LTable) repl).luaGetTable( vm, k ) );
|
vm.pushlvalue( ((LTable) repl).luaGetTable( vm, k ) );
|
||||||
} else {
|
} else {
|
||||||
vm.error( "string/function/table expected" );
|
vm.error( "bad argument: string/function/table expected" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@ require 'args'
|
|||||||
|
|
||||||
-- string.byte
|
-- string.byte
|
||||||
banner('string.byte')
|
banner('string.byte')
|
||||||
checkallpass('string.byte',{somestring,{nil,ainteger},{nil,ainteger}})
|
checkallpass('string.byte',{somestring})
|
||||||
|
checkallpass('string.byte',{somestring,somenumber})
|
||||||
|
checkallpass('string.byte',{somestring,somenumber,somenumber})
|
||||||
checkallerrors('string.byte',{somestring,{astring,afunction,atable}},'bad argument')
|
checkallerrors('string.byte',{somestring,{astring,afunction,atable}},'bad argument')
|
||||||
checkallerrors('string.byte',{notastring,{nil,111}},'bad argument')
|
checkallerrors('string.byte',{notastring,{nil,111}},'bad argument')
|
||||||
|
|
||||||
@@ -53,9 +55,9 @@ local somerepl = {astring,atable,afunction}
|
|||||||
local notarepl = {nil,aboolean}
|
local notarepl = {nil,aboolean}
|
||||||
banner('string.gsub')
|
banner('string.gsub')
|
||||||
checkallpass('string.gsub',{somestring,somestring,somerepl,{nil,-1}})
|
checkallpass('string.gsub',{somestring,somestring,somerepl,{nil,-1}})
|
||||||
checkallerrors('string.gsub',{notastring,somestring,somerepl},'bad argument #1')
|
checkallerrors('string.gsub',{nonstring,somestring,somerepl},'bad argument #1')
|
||||||
checkallerrors('string.gsub',{somestring,notastring,somerepl},'bad argument #2')
|
checkallerrors('string.gsub',{somestring,nonstring,somerepl},'bad argument #2')
|
||||||
checkallerrors('string.gsub',{{astring},{astring},notarepl},'bad argument #3')
|
checkallerrors('string.gsub',{{astring},{astring},notarepl},'bad argument')
|
||||||
checkallerrors('string.gsub',{{astring},{astring},somerepl,nonnumber},'bad argument #4')
|
checkallerrors('string.gsub',{{astring},{astring},somerepl,nonnumber},'bad argument #4')
|
||||||
|
|
||||||
-- string.len
|
-- string.len
|
||||||
@@ -72,8 +74,10 @@ checkallerrors('string.lower',{notastring},'bad argument #1')
|
|||||||
banner('string.match')
|
banner('string.match')
|
||||||
checkallpass('string.match',{somestring,somestring})
|
checkallpass('string.match',{somestring,somestring})
|
||||||
checkallpass('string.match',{somestring,somestring,{nil,-3,3}})
|
checkallpass('string.match',{somestring,somestring,{nil,-3,3}})
|
||||||
checkallerrors('string.match',{notastring,somestring},'bad argument #1')
|
checkallerrors('string.match',{},'bad argument #1')
|
||||||
checkallerrors('string.match',{somestring,notastring},'bad argument #2')
|
checkallerrors('string.match',{nonstring,somestring},'bad argument #1')
|
||||||
|
checkallerrors('string.match',{somestring},'bad argument #2')
|
||||||
|
checkallerrors('string.match',{somestring,nonstring},'bad argument #2')
|
||||||
checkallerrors('string.match',{somestring,somestring,notanumber},'bad argument #3')
|
checkallerrors('string.match',{somestring,somestring,notanumber},'bad argument #3')
|
||||||
|
|
||||||
-- string.reverse
|
-- string.reverse
|
||||||
@@ -89,9 +93,12 @@ checkallerrors('string.rep',{somestring,notanumber},'bad argument #2')
|
|||||||
|
|
||||||
-- string.sub
|
-- string.sub
|
||||||
banner('string.sub')
|
banner('string.sub')
|
||||||
|
checkallpass('string.sub',{somestring,somenumber})
|
||||||
checkallpass('string.sub',{somestring,somenumber,somenumber})
|
checkallpass('string.sub',{somestring,somenumber,somenumber})
|
||||||
checkallerrors('string.sub',{notastring,somenumber,somenumber},'bad argument #1')
|
checkallerrors('string.sub',{},'bad argument #1')
|
||||||
checkallerrors('string.sub',{somestring,notanumber,somenumber},'bad argument #2')
|
checkallerrors('string.sub',{nonstring,somenumber,somenumber},'bad argument #1')
|
||||||
|
checkallerrors('string.sub',{somestring},'bad argument #2')
|
||||||
|
checkallerrors('string.sub',{somestring,nonnumber,somenumber},'bad argument #2')
|
||||||
checkallerrors('string.sub',{somestring,somenumber,nonnumber},'bad argument #3')
|
checkallerrors('string.sub',{somestring,somenumber,nonnumber},'bad argument #3')
|
||||||
|
|
||||||
-- string.upper
|
-- string.upper
|
||||||
|
|||||||
Reference in New Issue
Block a user