From 0de9cf41eb2f77f98e0d7e74568bacc40cacb30a Mon Sep 17 00:00:00 2001 From: samisalreadytaken <46823719+samisalreadytaken@users.noreply.github.com> Date: Sat, 11 Dec 2021 22:20:00 +0300 Subject: [PATCH] Update Squirrel --- .../doc/source/stdlib/stdstringlib.rst | 8 +++- .../vscript/squirrel/sqstdlib/sqstdblob.cpp | 4 +- .../vscript/squirrel/sqstdlib/sqstdstring.cpp | 42 ++++++++++++------- .../vscript/squirrel/squirrel/sqbaselib.cpp | 14 +++++-- sp/src/vscript/squirrel/squirrel/sqclass.cpp | 3 ++ sp/src/vscript/squirrel/squirrel/sqclass.h | 1 + sp/src/vscript/squirrel/squirrel/sqtable.h | 2 +- 7 files changed, 51 insertions(+), 23 deletions(-) diff --git a/sp/src/vscript/squirrel/doc/source/stdlib/stdstringlib.rst b/sp/src/vscript/squirrel/doc/source/stdlib/stdstringlib.rst index 19c18d7a..dd929346 100644 --- a/sp/src/vscript/squirrel/doc/source/stdlib/stdstringlib.rst +++ b/sp/src/vscript/squirrel/doc/source/stdlib/stdstringlib.rst @@ -50,16 +50,20 @@ Global Symbols Strips white-space-only characters that might appear at the end of the given string and returns the new stripped string. -.. js:function:: split(str, separators) +.. js:function:: split(str, separators [, skipempty]) returns an array of strings split at each point where a separator character occurs in `str`. The separator is not returned as part of any array element. The parameter `separators` is a string that specifies the characters as to be used for the splitting. + The parameter `skipempty` is a boolean (default false). If `skipempty` is true, empty strings are not added to array. :: eg. - local a = split("1.2-3;4/5",".-/;"); + local a = split("1.2-3;;4/5",".-/;"); + // the result will be [1,2,3,,4,5] + or + local b = split("1.2-3;;4/5",".-/;",true); // the result will be [1,2,3,4,5] diff --git a/sp/src/vscript/squirrel/sqstdlib/sqstdblob.cpp b/sp/src/vscript/squirrel/sqstdlib/sqstdblob.cpp index 261b938b..776a9680 100644 --- a/sp/src/vscript/squirrel/sqstdlib/sqstdblob.cpp +++ b/sp/src/vscript/squirrel/sqstdlib/sqstdblob.cpp @@ -205,8 +205,8 @@ static SQInteger _g_blob_swap2(HSQUIRRELVM v) { SQInteger i; sq_getinteger(v,2,&i); - short s=(short)i; - sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); + unsigned short s = (unsigned short)i; + sq_pushinteger(v, ((s << 8) | ((s >> 8) & 0x00FFu)) & 0xFFFFu); return 1; } diff --git a/sp/src/vscript/squirrel/sqstdlib/sqstdstring.cpp b/sp/src/vscript/squirrel/sqstdlib/sqstdstring.cpp index 919bd9e9..5747d8ed 100644 --- a/sp/src/vscript/squirrel/sqstdlib/sqstdstring.cpp +++ b/sp/src/vscript/squirrel/sqstdlib/sqstdstring.cpp @@ -12,6 +12,8 @@ #define MAX_WFORMAT_LEN 3 #define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar)) +static SQUserPointer rex_typetag = NULL; + static SQBool isfmtchr(SQChar ch) { switch(ch) { @@ -247,16 +249,16 @@ static SQInteger _string_rstrip(HSQUIRRELVM v) static SQInteger _string_split(HSQUIRRELVM v) { const SQChar *str,*seps; - SQChar *stemp; + SQInteger sepsize; + SQBool skipempty = SQFalse; sq_getstring(v,2,&str); - sq_getstring(v,3,&seps); - SQInteger sepsize = sq_getsize(v,3); + sq_getstringandsize(v,3,&seps,&sepsize); if(sepsize == 0) return sq_throwerror(v,_SC("empty separators string")); - SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar); - stemp = sq_getscratchpad(v,memsize); - memcpy(stemp,str,memsize); - SQChar *start = stemp; - SQChar *end = stemp; + if(sq_gettop(v)>3) { + sq_getbool(v,4,&skipempty); + } + const SQChar *start = str; + const SQChar *end = str; sq_newarray(v,0); while(*end != '\0') { @@ -265,9 +267,10 @@ static SQInteger _string_split(HSQUIRRELVM v) { if(cur == seps[i]) { - *end = 0; - sq_pushstring(v,start,-1); - sq_arrayappend(v,-2); + if(!skipempty || (end != start)) { + sq_pushstring(v,start,end-start); + sq_arrayappend(v,-2); + } start = end + 1; break; } @@ -276,7 +279,7 @@ static SQInteger _string_split(HSQUIRRELVM v) } if(end != start) { - sq_pushstring(v,start,-1); + sq_pushstring(v,start,end-start); sq_arrayappend(v,-2); } return 1; @@ -384,7 +387,9 @@ static SQInteger _string_endswith(HSQUIRRELVM v) #define SETUP_REX(v) \ SQRex *self = NULL; \ - sq_getinstanceup(v,1,(SQUserPointer *)&self,0); + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer *)&self,rex_typetag))) { \ + return sq_throwerror(v,_SC("invalid type tag")); \ + } static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger SQ_UNUSED_ARG(size)) { @@ -465,6 +470,13 @@ static SQInteger _regexp_subexpcount(HSQUIRRELVM v) static SQInteger _regexp_constructor(HSQUIRRELVM v) { + SQRex *self = NULL; + if (SQ_FAILED(sq_getinstanceup(v, 1, (SQUserPointer *)&self, rex_typetag))) { + return sq_throwerror(v, _SC("invalid type tag")); + } + if (self != NULL) { + return sq_throwerror(v, _SC("invalid regexp object")); + } const SQChar *error,*pattern; sq_getstring(v,2,&pattern); SQRex *rex = sqstd_rex_compile(pattern,&error); @@ -499,7 +511,7 @@ static const SQRegFunction stringlib_funcs[]={ _DECL_FUNC(strip,2,_SC(".s")), _DECL_FUNC(lstrip,2,_SC(".s")), _DECL_FUNC(rstrip,2,_SC(".s")), - _DECL_FUNC(split,3,_SC(".ss")), + _DECL_FUNC(split,-3,_SC(".ssb")), _DECL_FUNC(escape,2,_SC(".s")), _DECL_FUNC(startswith,3,_SC(".ss")), _DECL_FUNC(endswith,3,_SC(".ss")), @@ -512,6 +524,8 @@ SQInteger sqstd_register_stringlib(HSQUIRRELVM v) { sq_pushstring(v,_SC("regexp"),-1); sq_newclass(v,SQFalse); + rex_typetag = (SQUserPointer)rexobj_funcs; + sq_settypetag(v, -1, rex_typetag); SQInteger i = 0; while(rexobj_funcs[i].name != 0) { const SQRegFunction &f = rexobj_funcs[i]; diff --git a/sp/src/vscript/squirrel/squirrel/sqbaselib.cpp b/sp/src/vscript/squirrel/squirrel/sqbaselib.cpp index fb6545f9..5c03e839 100644 --- a/sp/src/vscript/squirrel/squirrel/sqbaselib.cpp +++ b/sp/src/vscript/squirrel/squirrel/sqbaselib.cpp @@ -754,7 +754,7 @@ static SQInteger array_find(HSQUIRRELVM v) } -static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) +static bool _sort_compare(HSQUIRRELVM v, SQArray *arr, SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret) { if(func < 0) { if(!v->ObjCmp(a,b,ret)) return false; @@ -765,15 +765,21 @@ static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger sq_pushroottable(v); v->Push(a); v->Push(b); + SQObjectPtr *valptr = arr->_values._vals; + SQUnsignedInteger precallsize = arr->_values.size(); if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) { if(!sq_isstring( v->_lasterror)) v->Raise_Error(_SC("compare func failed")); return false; } - if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { + if(SQ_FAILED(sq_getinteger(v, -1, &ret))) { v->Raise_Error(_SC("numeric value expected as return value of the compare function")); return false; } + if (precallsize != arr->_values.size() || valptr != arr->_values._vals) { + v->Raise_Error(_SC("array resized during sort operation")); + return false; + } sq_settop(v, top); return true; } @@ -792,7 +798,7 @@ static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteg maxChild = root2; } else { - if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret)) + if(!_sort_compare(v,arr,arr->_values[root2],arr->_values[root2 + 1],func,ret)) return false; if (ret > 0) { maxChild = root2; @@ -802,7 +808,7 @@ static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteg } } - if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret)) + if(!_sort_compare(v,arr,arr->_values[root],arr->_values[maxChild],func,ret)) return false; if (ret < 0) { if (root == maxChild) { diff --git a/sp/src/vscript/squirrel/squirrel/sqclass.cpp b/sp/src/vscript/squirrel/squirrel/sqclass.cpp index fc619616..53a29763 100644 --- a/sp/src/vscript/squirrel/squirrel/sqclass.cpp +++ b/sp/src/vscript/squirrel/squirrel/sqclass.cpp @@ -61,6 +61,9 @@ bool SQClass::NewSlot(SQSharedState *ss,const SQObjectPtr &key,const SQObjectPtr _defaultvalues[_member_idx(temp)].val = val; return true; } + if (_members->CountUsed() >= MEMBER_MAX_COUNT) { + return false; + } if(belongs_to_static_table) { SQInteger mmidx; if((sq_type(val) == OT_CLOSURE || sq_type(val) == OT_NATIVECLOSURE) && diff --git a/sp/src/vscript/squirrel/squirrel/sqclass.h b/sp/src/vscript/squirrel/squirrel/sqclass.h index 7d402172..60d3d21b 100644 --- a/sp/src/vscript/squirrel/squirrel/sqclass.h +++ b/sp/src/vscript/squirrel/squirrel/sqclass.h @@ -17,6 +17,7 @@ typedef sqvector SQClassMemberVec; #define MEMBER_TYPE_METHOD 0x01000000 #define MEMBER_TYPE_FIELD 0x02000000 +#define MEMBER_MAX_COUNT 0x00FFFFFF #define _ismethod(o) (_integer(o)&MEMBER_TYPE_METHOD) #define _isfield(o) (_integer(o)&MEMBER_TYPE_FIELD) diff --git a/sp/src/vscript/squirrel/squirrel/sqtable.h b/sp/src/vscript/squirrel/squirrel/sqtable.h index 59db3317..8ca3ae7c 100644 --- a/sp/src/vscript/squirrel/squirrel/sqtable.h +++ b/sp/src/vscript/squirrel/squirrel/sqtable.h @@ -12,7 +12,7 @@ #define hashptr(p) ((SQHash)(((SQInteger)p) >> 3)) -inline SQHash HashObj(const SQObjectPtr &key) +inline SQHash HashObj(const SQObject &key) { switch(sq_type(key)) { case OT_STRING: return _string(key)->_hash;