CVE-2020-22875 (C, published 2021-07-13T15:15Z)
Description: value: Integer overflow vulnerability in function Jsi_ObjSetLength in jsish before 3.0.6, allows remote attackers to execute arbitrary code.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-190 \u2014 Integer Overflow or Wraparound
The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
Repository: https://github.com/pcmacdon/jsish
Files changed:
md/Reference.md
src/jsi.h
src/jsiArray.c
src/jsiCmds.c
tests/locals.jsi
tools/protos.jsi
www/reference.wiki
Commit message: Release "3.0.6": Fix crashes in Array for "integer overflow #10"

FossilOrigin-Name: 50642d64b8f0a4e62df68e59fcb2ef0923c3dbec8fc8a15d38b1ddbe655c38d6

Vulnerable code:
<tr><td>locals</td><td>locals(varsOnly:boolean=void):object </td><td>Return functions/vars inside local function.</td></tr>
#define JSI_VERSION_RELEASE 4
    int curlen = Jsi_ObjGetLength(interp, obj);
    if (curlen < 0) {
        Jsi_ObjSetLength(interp, obj, 0);
    }
    
    Jsi_ValueMakeNumber(interp, ret, Jsi_ObjGetLength(interp, obj));
    int i = Jsi_ObjGetLength(interp, obj) - 1;
    curlen = Jsi_ObjGetLength(interp, _this->d.obj);
    if (0 == (argc=Jsi_ObjGetLength(interp, _this->d.obj))) {
    int len = Jsi_ObjGetLength(interp, v->d.obj);
    int i, n = 0, len = Jsi_ObjGetLength(interp, arr->d.obj);
    int clen = Jsi_ObjGetLength(interp, nobj);
    curlen = Jsi_ObjGetLength(interp, obj);
    if (curlen < 0) {
        Jsi_ObjSetLength(interp, obj, 0);
    }
    curlen = Jsi_ObjGetLength(interp, obj);    
    if (curlen < 0) {
        Jsi_ObjSetLength(interp, obj, 0);
    }
    curlen = Jsi_ObjGetLength(interp, obj);    
    if (curlen < 0) {
        Jsi_ObjSetLength(interp, obj, 0);
    }
    int curlen;
    curlen = Jsi_ObjGetLength(interp, obj);    
    if (curlen < 0) {
        Jsi_ObjSetLength(interp, obj, 0);
    }
    int curlen;
    curlen = Jsi_ObjGetLength(interp, obj);    
    if (curlen < 0) {
        Jsi_ObjSetLength(interp, obj, 0);
    }
    int curlen, i;
    curlen = Jsi_ObjGetLength(interp, obj);    
    if (curlen < 0)
        Jsi_ObjSetLength(interp, obj, 0);
    n = Jsi_ObjGetLength(interp, obj);    
    int i = Jsi_ObjGetLength(interp, _this->d.obj);
    uint n = Jsi_ObjGetLength(interp, obj);
    assert(n <= obj->arrCnt);
    int curlen = Jsi_ObjGetLength(interp, obj);
    if (curlen < 0) {
        Jsi_ObjSetLength(interp, obj, 0);
    }
    Jsi_ValueMakeNumber(interp, ret, Jsi_ObjGetLength(interp, obj));
    n = Jsi_ObjGetLength(interp, obj);
    n = Jsi_ObjGetLength(interp, obj);
    n = Jsi_ObjGetLength(interp, obj);
        Jsi_ObjSetLength(interp, obj, 0);
    { "locals",     InfoLocalsCmd,      0,  1, "varsOnly:boolean=void", .help="Return functions/vars inside local function", .retType=(uint)JSI_TT_OBJECT },
//JSI Command Prototypes: version 3.0.4
Info.prototype.locals = function(varsOnly:boolean=void):object {};
<tr><td>locals</td><td>locals(varsOnly:boolean=void):object </td><td>Return functions/vars inside local function.</td></tr>

Fixed code:
<tr><td>locals</td><td>locals(filter:boolean=void):object </td><td>Return locals; use filter=true/false just vars/functions.</td></tr>
<tr><td>runMain</td><td>runMain(cmd:string|null|function=void, conf:array=undefined) </td><td>If isMain invokes runModule.</td></tr>
#define JSI_VERSION_RELEASE 6
static uint jsi_SizeOfArray(Jsi_Interp *interp, Jsi_Obj *obj) {
    if (!obj || !obj->arr)
        return 0;
    return obj->arrCnt;
}

    int curlen = jsi_SizeOfArray(interp, obj);    
    Jsi_ValueMakeNumber(interp, ret, jsi_SizeOfArray(interp, obj));
    int i = jsi_SizeOfArray(interp, obj) - 1;
    curlen = jsi_SizeOfArray(interp, _this->d.obj);
    if (0 == (argc=jsi_SizeOfArray(interp, _this->d.obj))) {
    int len = jsi_SizeOfArray(interp, v->d.obj);
    int i, n = 0, len = jsi_SizeOfArray(interp, arr->d.obj);
    int clen = jsi_SizeOfArray(interp, nobj);
    curlen = jsi_SizeOfArray(interp, obj);
    curlen = jsi_SizeOfArray(interp, obj);    
    curlen = jsi_SizeOfArray(interp, obj);    
    int i;
    n = jsi_SizeOfArray(interp, obj);    
    int i = jsi_SizeOfArray(interp, _this->d.obj);
    uint n = jsi_SizeOfArray(interp, obj);
    int curlen = jsi_SizeOfArray(interp, obj);
    Jsi_ValueMakeNumber(interp, ret, jsi_SizeOfArray(interp, obj));
    n = jsi_SizeOfArray(interp, obj);
    n = jsi_SizeOfArray(interp, obj);
    n = jsi_SizeOfArray(interp, obj);
        Jsi_ObjSetLength(interp, obj, curlen=0);
static Jsi_RC SysRunMainCmd(Jsi_Interp *interp, Jsi_Value *args, Jsi_Value *_this,
    Jsi_Value **ret, Jsi_Func *funcPtr)
{
    if (jsi_isMain(interp))
        return SysRunModuleCmd(interp, args, _this, ret, funcPtr);
    return JSI_OK;
}

    { "locals",     InfoLocalsCmd,      0,  1, "filter:boolean=void", .help="Return locals; use filter=true/false just vars/functions", .retType=(uint)JSI_TT_OBJECT },
    { "runMain",    SysRunMainCmd,   0,  2, "cmd:string|null|function=void, conf:array=undefined", .help="If isMain invokes runModule", .retType=(uint)JSI_TT_ANY, .flags=0},
function foo() {


  function bar() { }
  var x = 1;
;  Info.locals();
;  Info.locals(false);
;  Info.locals(true);
}

foo();

/*
=!EXPECTSTART!=
Info.locals() ==> { bar:"function bar() {...}", x:1 }
Info.locals(false) ==> { bar:"function bar() {...}" }
Info.locals(true) ==> { x:1 }
=!EXPECTEND!=
*/
//JSI Command Prototypes: version 3.0.6
Info.prototype.locals = function(filter:boolean=void):object {};
System.prototype.runMain = function(cmd:string|null|function=void, conf:array=undefined):any {};
var runMain = function(cmd:string|null|function=void, conf:array=undefined):any {};
<tr><td>locals</td><td>locals(filter:boolean=void):object </td><td>Return locals; use filter=true/false just vars/functions.</td></tr>
<tr><td>runMain</td><td>runMain(cmd:string|null|function=void, conf:array=undefined) </td><td>If isMain invokes runModule.</td></tr>