diff --git a/src/jsi.h b/src/jsi.h index ee6ea10..9326ad7 100644 --- a/src/jsi.h +++ b/src/jsi.h @@ -534,7 +534,7 @@ JSI_EXTERN Jsi_Value* Jsi_ValueNewFunction(Jsi_Interp *interp, Jsi_CmdProc *call #define Jsi_ValueNewBlobString(interp, s) Jsi_ValueNewBlob(interp, (uchar*)s, Jsi_Strlen(s)) #define Jsi_ValueNewArrayObj(interp, items, count, copy) Jsi_ValueNewObj(interp, Jsi_ObjNewArray(interp, items, count, copy)) -JSI_EXTERN Jsi_RC Jsi_GetStringFromValue(Jsi_Interp* interp, Jsi_Value *value, const char **s); /*STUB = 109*/ +JSI_EXTERN Jsi_RC Jsi_GetStringFromValue(Jsi_Interp* interp, Jsi_Value *value, const char **sPtr, int *lenPtr); /*STUB = 109*/ JSI_EXTERN Jsi_RC Jsi_GetNumberFromValue(Jsi_Interp* interp, Jsi_Value *value, Jsi_Number *n); /*STUB = 110*/ JSI_EXTERN Jsi_RC Jsi_GetBoolFromValue(Jsi_Interp* interp, Jsi_Value *value, bool *n); /*STUB = 111*/ JSI_EXTERN Jsi_RC Jsi_GetIntFromValue(Jsi_Interp* interp, Jsi_Value *value, int *n); /*STUB = 112*/ diff --git a/src/jsiEval.c b/src/jsiEval.c index db848dd..ca91ef4 100644 --- a/src/jsiEval.c +++ b/src/jsiEval.c @@ -258,9 +258,6 @@ static Jsi_RC jsiLogicLess(Jsi_Interp* interp, int i1, int i2) { str = Jsi_ValueString(interp, v, (s1?&l2:&l1)); if (s1) s2 = str; else s1 = str; } - Assert(l1>=0 && l1<=JSI_MAX_ALLOC_BUF); - Assert(l2>=0 && l2<=JSI_MAX_ALLOC_BUF); - //int mlen = (l1>l2?l1:l2); val = Jsi_Strcmp(s1, s2); if (val > 0) val = 0; @@ -1410,7 +1407,7 @@ Jsi_RC jsiEvalCodeSub(jsi_Pstate *ps, Jsi_OpCodes *opcodes, case OP_ADD: { jsiVarDeref(interp,2); Jsi_Value *v, *v1 = _jsi_TOP, *v2 = _jsi_TOQ; - int l1, l2; + int l1, l2, lnew; if (strict) if (Jsi_ValueIsUndef(interp, v1) || Jsi_ValueIsUndef(interp, v2)) { rc = Jsi_LogError("operand value to + is undefined"); @@ -1429,12 +1426,17 @@ Jsi_RC jsiEvalCodeSub(jsi_Pstate *ps, Jsi_OpCodes *opcodes, } Assert(l1>=0 && l1<=JSI_MAX_ALLOC_BUF); Assert(l2>=0 && l2<=JSI_MAX_ALLOC_BUF); - str = (char*)Jsi_Malloc(l1+l2+1); - memcpy(str, s2, l2); - memcpy(str+l2, s1, l1); - str[l1+l2] = 0; - jsiClearStack(interp,2); - Jsi_ValueMakeBlob(interp, &v2, (uchar*)str, l1+l2); + lnew = l1+l2+1; + if (lnew >= JSI_MAX_ALLOC_BUF) + rc = Jsi_LogError("string longer than max alloc size"); + else { + str = (char*)Jsi_Malloc(lnew); + memcpy(str, s2, l2); + memcpy(str+l2, s1, l1); + str[l1+l2] = 0; + jsiClearStack(interp,2); + Jsi_ValueMakeBlob(interp, &v2, (uchar*)str, l1+l2); + } } else { Jsi_ValueToNumber(interp, v1); Jsi_ValueToNumber(interp, v2); diff --git a/src/jsiFormat.c b/src/jsiFormat.c index acde79a..7dc4747 100644 --- a/src/jsiFormat.c +++ b/src/jsiFormat.c @@ -284,9 +284,8 @@ Jsi_RC Jsi_FormatString(Jsi_Interp *interp, Jsi_Value *args, Jsi_DString *dStr) } else Jsi_ValueToString(interp, v, NULL); if (!(formatted_buf = Jsi_ValueString(interp, v, &formatted_chars))) { - if (Jsi_GetStringFromValue(interp, v, &formatted_buf) != JSI_OK) + if (Jsi_GetStringFromValue(interp, v, &formatted_buf, &formatted_chars) != JSI_OK) goto error; - formatted_chars = Jsi_Strlen(formatted_buf); } doprec: formatted_bytes = formatted_chars; diff --git a/src/jsiOptions.c b/src/jsiOptions.c index d71f3c9..1a2f903 100644 --- a/src/jsiOptions.c +++ b/src/jsiOptions.c @@ -367,7 +367,7 @@ jsi_SetOption_(Jsi_Interp *interp, Jsi_OptionSpec *specPtr, const char *string / goto bail; } else { const char *scp; - if (Jsi_GetStringFromValue(interp, argValue, &scp) != JSI_OK) { + if (Jsi_GetStringFromValue(interp, argValue, &scp, NULL) != JSI_OK) { return JSI_ERROR; } *(const char**)ptr = Jsi_KeyAdd(interp,scp); @@ -437,7 +437,7 @@ jsi_SetOption_(Jsi_Interp *interp, Jsi_OptionSpec *specPtr, const char *string / *(double*)ptr = nv; } else { const char *scp; - if (Jsi_GetStringFromValue(interp, argValue, &scp) != JSI_OK) { + if (Jsi_GetStringFromValue(interp, argValue, &scp, NULL) != JSI_OK) { goto bail; } if (JSI_OK != Jsi_DatetimeParse(interp, scp, "", 0, &nv, false)) @@ -457,7 +457,7 @@ jsi_SetOption_(Jsi_Interp *interp, Jsi_OptionSpec *specPtr, const char *string / } else { const char *scp; Jsi_Number num; - if (Jsi_GetStringFromValue(interp, argValue, &scp) != JSI_OK) { + if (Jsi_GetStringFromValue(interp, argValue, &scp, NULL) != JSI_OK) { goto bail; } if (JSI_OK != Jsi_DatetimeParse(interp, scp, "", 0, &num, false)) @@ -478,7 +478,7 @@ jsi_SetOption_(Jsi_Interp *interp, Jsi_OptionSpec *specPtr, const char *string / *(time_t*)ptr = (time_t)num; } else { const char *scp; - if (Jsi_GetStringFromValue(interp, argValue, &scp) != JSI_OK) { + if (Jsi_GetStringFromValue(interp, argValue, &scp, NULL) != JSI_OK) { goto bail; } Jsi_Number nval; diff --git a/src/jsiString.c b/src/jsiString.c index c3f8eb4..d0c710e 100644 --- a/src/jsiString.c +++ b/src/jsiString.c @@ -209,16 +209,16 @@ static Jsi_RC StringRepeatCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_t Jsi_Number ncnt; if (!start || Jsi_GetNumberFromValue(interp,start, &ncnt) != JSI_OK || ncnt>MAX_LOOP_COUNT || ncnt<0 || bLen<=0) { - return JSI_ERROR; + return Jsi_LogError("count out of range");; } int cnt = (int)ncnt; Jsi_DString dStr = {}; while (cnt-- > 0) { - Jsi_DSAppendLen(&dStr, v, bLen); - if (Jsi_DSLength(&dStr)>JSI_MAX_ALLOC_BUF) { + if ((Jsi_DSLength(&dStr)+bLen)>=JSI_MAX_ALLOC_BUF) { Jsi_DSFree(&dStr); return Jsi_LogError("too long"); } + Jsi_DSAppendLen(&dStr, v, bLen); } Jsi_ValueFromDS(interp, &dStr, ret); return JSI_OK; @@ -522,12 +522,17 @@ static Jsi_RC StringConcatCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_t for (i=skip; i=JSI_MAX_ALLOC_BUF) { + Jsi_DSFree(&dStr); + return Jsi_LogError("too long"); + } + Jsi_DSAppendLen(&dStr, vstr, sLen); } Jsi_ValueFromDS(interp, &dStr, ret); @@ -609,6 +614,10 @@ static Jsi_RC StringMapCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this int res = (nocase ? Jsi_Strncasecmp(cp, p, slen) : Jsi_Strncmp(cp, p, slen)); if (!res) { replace_str = Jsi_ValueToString(interp, obj->arr[i+1], &replace_len); + if ((Jsi_DSLength(&dStr)+replace_len+1)>=JSI_MAX_ALLOC_BUF) { + Jsi_DSFree(&dStr); + return Jsi_LogError("too long"); + } Jsi_DSAppendLen(&dStr, replace_str, replace_len); p += slen-1; j += slen-1; @@ -669,9 +678,13 @@ static Jsi_RC StringReplaceCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_ slen = (ce-source_str); if (slen) Jsi_DSAppendLen(&dStr, source_str, slen); - if (replace_str) + if (replace_str) { + if ((Jsi_DSLength(&dStr)+replace_len)>=JSI_MAX_ALLOC_BUF) { + Jsi_DSFree(&dStr); + return Jsi_LogError("too long"); + } Jsi_DSAppendLen(&dStr, replace_str, replace_len); - else { + } else { Jsi_Value *inStr = Jsi_ValueNewStringDup(interp, source_str); Jsi_IncrRefCount(interp, inStr); Jsi_RC rc = Jsi_FunctionInvokeString(interp, repVal, inStr, &dStr, _this); diff --git a/src/jsiStubs.h b/src/jsiStubs.h index 858659f..ef9aeea 100644 --- a/src/jsiStubs.h +++ b/src/jsiStubs.h @@ -5,7 +5,7 @@ #endif -#define JSI_STUBS_MD5 "aff068ab3a03d873e96f46a828943e9b" +#define JSI_STUBS_MD5 "35c36c383d326b0ea9203585674dc009" #undef JSI_EXTENSION_INI #define JSI_EXTENSION_INI Jsi_Stubs *jsiStubsPtr = NULL; @@ -137,7 +137,7 @@ typedef struct Jsi_Stubs { Jsi_Value*(*_Jsi_ValueNewStringDup)(Jsi_Interp *interp, const char *s); Jsi_Value*(*_Jsi_ValueNewArray)(Jsi_Interp *interp, const char **items, int count); Jsi_Value*(*_Jsi_ValueNewObj)(Jsi_Interp *interp, Jsi_Obj *o); - Jsi_RC(*_Jsi_GetStringFromValue)(Jsi_Interp* interp, Jsi_Value *value, const char **s); + Jsi_RC(*_Jsi_GetStringFromValue)(Jsi_Interp* interp, Jsi_Value *value, const char **sPtr, int *lenPtr); Jsi_RC(*_Jsi_GetNumberFromValue)(Jsi_Interp* interp, Jsi_Value *value, Jsi_Number *n); Jsi_RC(*_Jsi_GetBoolFromValue)(Jsi_Interp* interp, Jsi_Value *value, bool *n); Jsi_RC(*_Jsi_GetIntFromValue)(Jsi_Interp* interp, Jsi_Value *value, int *n); @@ -1005,7 +1005,7 @@ extern Jsi_Stubs* jsiStubsPtr; #define Jsi_ValueNewStringDup(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_ValueNewStringDup(n0,n1)) #define Jsi_ValueNewArray(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_ValueNewArray(n0,n1,n2)) #define Jsi_ValueNewObj(n0,n1) JSISTUBCALL(jsiStubsPtr, _Jsi_ValueNewObj(n0,n1)) -#define Jsi_GetStringFromValue(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_GetStringFromValue(n0,n1,n2)) +#define Jsi_GetStringFromValue(n0,n1,n2,n3) JSISTUBCALL(jsiStubsPtr, _Jsi_GetStringFromValue(n0,n1,n2,n3)) #define Jsi_GetNumberFromValue(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_GetNumberFromValue(n0,n1,n2)) #define Jsi_GetBoolFromValue(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_GetBoolFromValue(n0,n1,n2)) #define Jsi_GetIntFromValue(n0,n1,n2) JSISTUBCALL(jsiStubsPtr, _Jsi_GetIntFromValue(n0,n1,n2)) diff --git a/src/jsiUtils.c b/src/jsiUtils.c index d8845dc..7be5292 100644 --- a/src/jsiUtils.c +++ b/src/jsiUtils.c @@ -2561,21 +2561,19 @@ void Jsi_InterpFreeData(Jsi_Interp *interp, const char *key) Jsi_HashEntryDelete(hPtr); } -Jsi_RC Jsi_GetStringFromValue(Jsi_Interp* interp, Jsi_Value *value, const char **n) +Jsi_RC Jsi_GetStringFromValue(Jsi_Interp* interp, Jsi_Value *value, const char **sPtr, int *lenPtr) { if (!value) return JSI_ERROR; - if (value->vt == JSI_VT_STRING) - { - *n = (const char*)value->d.s.str; - return JSI_OK; - } - if (value->vt == JSI_VT_OBJECT && value->d.obj->ot == JSI_OT_STRING) { - *n = value->d.obj->d.s.str; - return JSI_OK; - } - Jsi_LogError("invalid string"); - return JSI_ERROR; + int len; + const char *s = Jsi_ValueString(interp, value, &len); + if (!s) + return Jsi_LogError("invalid string"); + if (sPtr) + *sPtr = s; + if (lenPtr) + *lenPtr = len; + return JSI_OK; } Jsi_RC Jsi_GetBoolFromValue(Jsi_Interp* interp, Jsi_Value *value, bool *n)