fixed a double-free issue in eval_getbline()
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
103
lib/run.c
103
lib/run.c
@@ -7898,7 +7898,7 @@ static hawk_val_t* __eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|||||||
{
|
{
|
||||||
hawk_nde_getline_t* p;
|
hawk_nde_getline_t* p;
|
||||||
hawk_val_t* v = HAWK_NULL, * tmp;
|
hawk_val_t* v = HAWK_NULL, * tmp;
|
||||||
hawk_oocs_t dst;
|
hawk_oocs_t dst = { HAWK_NULL, 0 };
|
||||||
hawk_ooecs_t* buf;
|
hawk_ooecs_t* buf;
|
||||||
int n, x;
|
int n, x;
|
||||||
|
|
||||||
@@ -7915,8 +7915,6 @@ static hawk_val_t* __eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|||||||
v = io_nde_to_str(rtx, p->in, &dst, 0);
|
v = io_nde_to_str(rtx, p->in, &dst, 0);
|
||||||
if (!v || dst.len <= 0)
|
if (!v || dst.len <= 0)
|
||||||
{
|
{
|
||||||
hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
|
||||||
hawk_rtx_refdownval(rtx, v);
|
|
||||||
n = -1;
|
n = -1;
|
||||||
goto skip_read;
|
goto skip_read;
|
||||||
}
|
}
|
||||||
@@ -7933,12 +7931,6 @@ read_console_again:
|
|||||||
|
|
||||||
n = hawk_rtx_readio(rtx, p->in_type, dst.ptr, buf);
|
n = hawk_rtx_readio(rtx, p->in_type, dst.ptr, buf);
|
||||||
|
|
||||||
if (v)
|
|
||||||
{
|
|
||||||
hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
|
||||||
hawk_rtx_refdownval(rtx, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
{
|
{
|
||||||
/* make getline return -1 */
|
/* make getline return -1 */
|
||||||
@@ -7948,7 +7940,7 @@ read_console_again:
|
|||||||
* getline x[++j]
|
* getline x[++j]
|
||||||
* withtout do_assignment(), ++j is skipped when getline returns 0. */
|
* withtout do_assignment(), ++j is skipped when getline returns 0. */
|
||||||
tmp = do_assignment(rtx, p->var, hawk_val_zls);
|
tmp = do_assignment(rtx, p->var, hawk_val_zls);
|
||||||
if (HAWK_UNLIKELY(!tmp)) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!tmp)) goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /*if (n > 0)*/
|
else /*if (n > 0)*/
|
||||||
@@ -7961,7 +7953,7 @@ read_console_again:
|
|||||||
/* record filter based on record number(NR) */
|
/* record filter based on record number(NR) */
|
||||||
if (((rtx->gbl.nr / rtx->nrflt.limit) % rtx->nrflt.size) != rtx->nrflt.rank)
|
if (((rtx->gbl.nr / rtx->nrflt.limit) % rtx->nrflt.size) != rtx->nrflt.rank)
|
||||||
{
|
{
|
||||||
if (update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) return HAWK_NULL;
|
if (update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) goto oops;
|
||||||
/* this jump is a bit dirty. the 'if' block below hawk_rtx_readio()
|
/* this jump is a bit dirty. the 'if' block below hawk_rtx_readio()
|
||||||
* will never be true. but this makes code confusing */
|
* will never be true. but this makes code confusing */
|
||||||
goto read_console_again;
|
goto read_console_again;
|
||||||
@@ -7973,46 +7965,60 @@ read_console_again:
|
|||||||
{
|
{
|
||||||
/* set $0 with the input value */
|
/* set $0 with the input value */
|
||||||
x = hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(buf), 1);
|
x = hawk_rtx_setrec(rtx, 0, HAWK_OOECS_OOCS(buf), 1);
|
||||||
if (x <= -1) return HAWK_NULL;
|
if (x <= -1) goto oops;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hawk_val_t* v;
|
hawk_val_t* vv;
|
||||||
|
|
||||||
/* treat external input numerically if it can compose a number. */
|
/* treat external input numerically if it can compose a number. */
|
||||||
/*v = hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(buf));*/
|
/*vv = hawk_rtx_makestrvalwithoocs(rtx, HAWK_OOECS_OOCS(buf));*/
|
||||||
v = hawk_rtx_makenumorstrvalwithoochars(rtx, HAWK_OOECS_PTR(buf), HAWK_OOECS_LEN(buf));
|
vv = hawk_rtx_makenumorstrvalwithoochars(rtx, HAWK_OOECS_PTR(buf), HAWK_OOECS_LEN(buf));
|
||||||
if (HAWK_UNLIKELY(!v))
|
if (HAWK_UNLIKELY(!vv))
|
||||||
{
|
{
|
||||||
ADJERR_LOC(rtx, &nde->loc);
|
ADJERR_LOC(rtx, &nde->loc);
|
||||||
return HAWK_NULL;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
hawk_rtx_refupval(rtx, v);
|
hawk_rtx_refupval(rtx, vv);
|
||||||
tmp = do_assignment(rtx, p->var, v);
|
tmp = do_assignment(rtx, p->var, vv);
|
||||||
hawk_rtx_refdownval(rtx, v);
|
hawk_rtx_refdownval(rtx, vv);
|
||||||
if (HAWK_UNLIKELY(!tmp)) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!tmp)) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update FNR & NR if reading from console */
|
/* update FNR & NR if reading from console */
|
||||||
if (p->in_type == HAWK_IN_CONSOLE &&
|
if (p->in_type == HAWK_IN_CONSOLE &&
|
||||||
update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1)
|
update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1)
|
||||||
{
|
{
|
||||||
return HAWK_NULL;
|
goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_read:
|
skip_read:
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
if (dst.ptr) hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
||||||
|
hawk_rtx_refdownval(rtx, v);
|
||||||
|
}
|
||||||
|
|
||||||
tmp = hawk_rtx_makeintval(rtx, n);
|
tmp = hawk_rtx_makeintval(rtx, n);
|
||||||
if (HAWK_UNLIKELY(!tmp)) ADJERR_LOC(rtx, &nde->loc);
|
if (HAWK_UNLIKELY(!tmp)) ADJERR_LOC(rtx, &nde->loc);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
if (dst.ptr) hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
||||||
|
hawk_rtx_refdownval(rtx, v);
|
||||||
|
}
|
||||||
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hawk_val_t* __eval_getbline (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
static hawk_val_t* __eval_getbline (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||||
{
|
{
|
||||||
hawk_nde_getline_t* p;
|
hawk_nde_getline_t* p;
|
||||||
hawk_val_t* v = HAWK_NULL, * tmp;
|
hawk_val_t* v = HAWK_NULL, * tmp;
|
||||||
hawk_oocs_t dst;
|
hawk_oocs_t dst = {HAWK_NULL, 0};
|
||||||
hawk_becs_t* buf;
|
hawk_becs_t* buf;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
@@ -8029,8 +8035,6 @@ static hawk_val_t* __eval_getbline (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
|||||||
v = io_nde_to_str(rtx, p->in, &dst, 0);
|
v = io_nde_to_str(rtx, p->in, &dst, 0);
|
||||||
if (!v || dst.len <= 0)
|
if (!v || dst.len <= 0)
|
||||||
{
|
{
|
||||||
hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
|
||||||
hawk_rtx_refdownval(rtx, v);
|
|
||||||
n = -1;
|
n = -1;
|
||||||
goto skip_read;
|
goto skip_read;
|
||||||
}
|
}
|
||||||
@@ -8047,19 +8051,13 @@ read_console_again:
|
|||||||
|
|
||||||
n = hawk_rtx_readiobytes(rtx, p->in_type, dst.ptr, buf);
|
n = hawk_rtx_readiobytes(rtx, p->in_type, dst.ptr, buf);
|
||||||
|
|
||||||
if (v)
|
|
||||||
{
|
|
||||||
hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
|
||||||
hawk_rtx_refdownval(rtx, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n <= 0)
|
if (n <= 0)
|
||||||
{
|
{
|
||||||
/* make getline return -1 or 0*/
|
/* make getline return -1 or 0*/
|
||||||
if (p->var)
|
if (p->var)
|
||||||
{
|
{
|
||||||
tmp = do_assignment(rtx, p->var, v);
|
tmp = do_assignment(rtx, p->var, hawk_val_zls);
|
||||||
if (tmp == HAWK_NULL) return HAWK_NULL;
|
if (HAWK_UNLIKELY(!tmp)) goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else /*if (n > 0)*/
|
else /*if (n > 0)*/
|
||||||
@@ -8072,7 +8070,7 @@ read_console_again:
|
|||||||
/* record filter based on record number(NR) */
|
/* record filter based on record number(NR) */
|
||||||
if (((rtx->gbl.nr / rtx->nrflt.limit) % rtx->nrflt.size) != rtx->nrflt.rank)
|
if (((rtx->gbl.nr / rtx->nrflt.limit) % rtx->nrflt.size) != rtx->nrflt.rank)
|
||||||
{
|
{
|
||||||
if (update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) return HAWK_NULL;
|
if (update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1) goto oops;
|
||||||
/* this jump is a bit dirty. the 'if' block below hawk_rtx_readio()
|
/* this jump is a bit dirty. the 'if' block below hawk_rtx_readio()
|
||||||
* will never be true. but this makes code confusing */
|
* will never be true. but this makes code confusing */
|
||||||
goto read_console_again;
|
goto read_console_again;
|
||||||
@@ -8084,42 +8082,55 @@ read_console_again:
|
|||||||
{
|
{
|
||||||
/* set $0 with the input value */
|
/* set $0 with the input value */
|
||||||
/*x = hawk_rtx_setbrec(rtx, 0, HAWK_BECS_BCS(buf));
|
/*x = hawk_rtx_setbrec(rtx, 0, HAWK_BECS_BCS(buf));
|
||||||
if (x <= -1) return HAWK_NULL;*/
|
if (x <= -1) goto oops;*/
|
||||||
/* TODO: can i support this? */
|
/* TODO: can i support this? */
|
||||||
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_ENOIMPL, HAWK_T("getbline without a variable not supported"));
|
hawk_rtx_seterrfmt(rtx, &nde->loc, HAWK_ENOIMPL, HAWK_T("getbline without a variable not supported"));
|
||||||
return HAWK_NULL;
|
goto oops;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hawk_val_t* v;
|
hawk_val_t* vv;
|
||||||
|
|
||||||
/* treat external input numerically if it can compose a number. */
|
/* treat external input numerically if it can compose a number. */
|
||||||
/*v = hawk_rtx_makembsvalwithbcs(rtx, HAWK_BECS_BCS(buf));*/
|
/*vv = hawk_rtx_makembsvalwithbcs(rtx, HAWK_BECS_BCS(buf));*/
|
||||||
v = hawk_rtx_makenumormbsvalwithbchars(rtx, HAWK_BECS_PTR(buf), HAWK_BECS_LEN(buf));
|
vv = hawk_rtx_makenumormbsvalwithbchars(rtx, HAWK_BECS_PTR(buf), HAWK_BECS_LEN(buf));
|
||||||
if (v == HAWK_NULL)
|
if (vv == HAWK_NULL)
|
||||||
{
|
{
|
||||||
ADJERR_LOC(rtx, &nde->loc);
|
ADJERR_LOC(rtx, &nde->loc);
|
||||||
return HAWK_NULL;
|
goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
hawk_rtx_refupval(rtx, v);
|
hawk_rtx_refupval(rtx, vv);
|
||||||
tmp = do_assignment(rtx, p->var, v);
|
tmp = do_assignment(rtx, p->var, vv);
|
||||||
hawk_rtx_refdownval(rtx, v);
|
hawk_rtx_refdownval(rtx, vv);
|
||||||
if (tmp == HAWK_NULL) return HAWK_NULL;
|
if (tmp == HAWK_NULL) goto oops;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update FNR & NR if reading from console */
|
/* update FNR & NR if reading from console */
|
||||||
if (p->in_type == HAWK_IN_CONSOLE &&
|
if (p->in_type == HAWK_IN_CONSOLE &&
|
||||||
update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1)
|
update_fnr(rtx, rtx->gbl.fnr + 1, rtx->gbl.nr + 1) <= -1)
|
||||||
{
|
{
|
||||||
return HAWK_NULL;
|
goto oops;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_read:
|
skip_read:
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
if (dst.ptr) hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
||||||
|
hawk_rtx_refdownval(rtx, v);
|
||||||
|
}
|
||||||
tmp = hawk_rtx_makeintval(rtx, n);
|
tmp = hawk_rtx_makeintval(rtx, n);
|
||||||
if (!tmp) ADJERR_LOC(rtx, &nde->loc);
|
if (!tmp) ADJERR_LOC(rtx, &nde->loc);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
||||||
|
oops:
|
||||||
|
if (v)
|
||||||
|
{
|
||||||
|
if (dst.ptr) hawk_rtx_freevaloocstr(rtx, v, dst.ptr);
|
||||||
|
hawk_rtx_refdownval(rtx, v);
|
||||||
|
}
|
||||||
|
return HAWK_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hawk_val_t* eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
static hawk_val_t* eval_getline (hawk_rtx_t* rtx, hawk_nde_t* nde)
|
||||||
|
|||||||
Reference in New Issue
Block a user