On Sun, Aug 25, 2019 at 08:32:04PM +0800, Michael Mikonos wrote: > Hello, > > I noticed that flex is too trusting and assumes > calloc/malloc will always succeed. Hopefully I > caught all of them. > I tried to follow the existing idiom of > calling flexerror() and passing strings via > the _() macro. OK?
Does upstream have anything like this? You could consider using the xmalloc idiom (i.e. have separate functions that do the checks). -Otto > > - Michael > > > Index: dfa.c > =================================================================== > RCS file: /cvs/src/usr.bin/lex/dfa.c,v > retrieving revision 1.8 > diff -u -p -U4 -r1.8 dfa.c > --- dfa.c 19 Nov 2015 23:20:34 -0000 1.8 > +++ dfa.c 25 Aug 2019 12:09:54 -0000 > @@ -526,15 +526,19 @@ void ntod () > yynxt_tbl = > (struct yytbl_data *) calloc (1, > sizeof (struct > yytbl_data)); > + if (yynxt_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init (yynxt_tbl, YYTD_ID_NXT); > yynxt_tbl->td_hilen = 1; > yynxt_tbl->td_lolen = num_full_table_rows; > yynxt_tbl->td_data = yynxt_data = > (flex_int32_t *) calloc (yynxt_tbl->td_lolen * > yynxt_tbl->td_hilen, > sizeof (flex_int32_t)); > + if (yynxt_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > yynxt_curr = 0; > > buf_prints (&yydmap_buf, > "\t{YYTD_ID_NXT, (void**)&yy_nxt, sizeof(%s)},\n", > Index: gen.c > =================================================================== > RCS file: /cvs/src/usr.bin/lex/gen.c,v > retrieving revision 1.15 > diff -u -p -U4 -r1.15 gen.c > --- gen.c 19 Nov 2015 23:28:03 -0000 1.15 > +++ gen.c 25 Aug 2019 12:09:55 -0000 > @@ -111,13 +111,17 @@ mkeoltbl(void) > flex_int8_t *tdata = NULL; > struct yytbl_data *tbl; > > tbl = calloc(1, sizeof(struct yytbl_data)); > + if (tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(tbl, YYTD_ID_RULE_CAN_MATCH_EOL); > tbl->td_flags = YYTD_DATA8; > tbl->td_lolen = num_rules + 1; > tbl->td_data = tdata = > calloc(tbl->td_lolen, sizeof(flex_int8_t)); > + if (tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > for (i = 1; i <= num_rules; i++) > tdata[i] = rule_has_nl[i] ? 1 : 0; > > @@ -223,15 +227,19 @@ mkctbl(void) > ((tblend + numecs + 1) >= INT16_MAX > || long_align) ? "flex_int32_t" : "flex_int16_t"); > > tbl = calloc(1, sizeof(struct yytbl_data)); > + if (tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(tbl, YYTD_ID_TRANSITION); > tbl->td_flags = YYTD_DATA32 | YYTD_STRUCT; > tbl->td_hilen = 0; > tbl->td_lolen = tblend + numecs + 1; /* number of structs */ > > tbl->td_data = tdata = > calloc(tbl->td_lolen * 2, sizeof(flex_int32_t)); > + if (tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > /* > * We want the transition to be represented as the offset to the next > * state, not the actual state number, which is what it currently is. > @@ -318,15 +326,19 @@ mkssltbl(void) > flex_int32_t *tdata = NULL; > flex_int32_t i; > > tbl = calloc(1, sizeof(struct yytbl_data)); > + if (tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(tbl, YYTD_ID_START_STATE_LIST); > tbl->td_flags = YYTD_DATA32 | YYTD_PTRANS; > tbl->td_hilen = 0; > tbl->td_lolen = lastsc * 2 + 1; > > tbl->td_data = tdata = > calloc(tbl->td_lolen, sizeof(flex_int32_t)); > + if (tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > for (i = 0; i <= lastsc * 2; ++i) > tdata[i] = base[i]; > > @@ -452,15 +464,19 @@ mkecstbl(void) > struct yytbl_data *tbl = NULL; > flex_int32_t *tdata = NULL; > > tbl = calloc(1, sizeof(struct yytbl_data)); > + if (tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(tbl, YYTD_ID_EC); > tbl->td_flags |= YYTD_DATA32; > tbl->td_hilen = 0; > tbl->td_lolen = csize; > > tbl->td_data = tdata = > calloc(tbl->td_lolen, sizeof(flex_int32_t)); > + if (tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > for (i = 1; i < csize; ++i) { > ecgroup[i] = ABS(ecgroup[i]); > tdata[i] = ecgroup[i]; > @@ -659,16 +675,19 @@ mkftbl(void) > struct yytbl_data *tbl; > flex_int32_t *tdata = NULL; > > tbl = calloc(1, sizeof(struct yytbl_data)); > + if (tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(tbl, YYTD_ID_ACCEPT); > tbl->td_flags |= YYTD_DATA32; > tbl->td_hilen = 0; /* it's a one-dimensional array */ > tbl->td_lolen = lastdfa + 1; > > tbl->td_data = tdata = > calloc(tbl->td_lolen, sizeof(flex_int32_t)); > - > + if (tbl->td_data == NULL) > + flexerror(_("calloc failed")); > dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action; > > for (i = 1; i <= lastdfa; ++i) { > int anum = dfaacc[i].dfaacc_state; > @@ -1102,12 +1121,16 @@ gentabs() > "\t{YYTD_ID_ACCLIST, (void**)&yy_acclist, sizeof(%s)},\n", > long_align ? "flex_int32_t" : "flex_int16_t"); > > yyacclist_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yyacclist_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yyacclist_tbl, YYTD_ID_ACCLIST); > yyacclist_tbl->td_lolen = MAX(numas, 1) + 1; > yyacclist_tbl->td_data = yyacclist_data = > calloc(yyacclist_tbl->td_lolen, sizeof(flex_int32_t)); > + if (yyacclist_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > yyacclist_curr = 1; > > j = 1; /* index into "yy_acclist" array */ > > @@ -1212,12 +1235,16 @@ gentabs() > "\t{YYTD_ID_ACCEPT, (void**)&yy_accept, sizeof(%s)},\n", > long_align ? "flex_int32_t" : "flex_int16_t"); > > yyacc_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yyacc_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yyacc_tbl, YYTD_ID_ACCEPT); > yyacc_tbl->td_lolen = k; > yyacc_tbl->td_data = yyacc_data = > calloc(yyacc_tbl->td_lolen, sizeof(flex_int32_t)); > + if (yyacc_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > yyacc_curr = 1; > > for (i = 1; i <= lastdfa; ++i) { > mkdata(acc_array[i]); > @@ -1268,13 +1295,17 @@ gentabs() > * templates with). > */ > flex_int32_t *yymecs_data = NULL; > yymeta_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yymeta_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yymeta_tbl, YYTD_ID_META); > yymeta_tbl->td_lolen = numecs + 1; > yymeta_tbl->td_data = yymecs_data = > calloc(yymeta_tbl->td_lolen, > sizeof(flex_int32_t)); > + if (yymeta_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > if (trace) > fputs(_("\n\nMeta-Equivalence Classes:\n"), > stderr); > @@ -1315,13 +1346,17 @@ gentabs() > "\t{YYTD_ID_BASE, (void**)&yy_base, sizeof(%s)},\n", > (tblend >= INT16_MAX > || long_align) ? "flex_int32_t" : "flex_int16_t"); > yybase_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yybase_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yybase_tbl, YYTD_ID_BASE); > yybase_tbl->td_lolen = total_states + 1; > yybase_tbl->td_data = yybase_data = > calloc(yybase_tbl->td_lolen, > sizeof(flex_int32_t)); > + if (yybase_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > yybase_curr = 1; > > for (i = 1; i <= lastdfa; ++i) { > int d = def[i]; > @@ -1372,12 +1407,16 @@ gentabs() > (total_states >= INT16_MAX > || long_align) ? "flex_int32_t" : "flex_int16_t"); > > yydef_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yydef_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yydef_tbl, YYTD_ID_DEF); > yydef_tbl->td_lolen = total_states + 1; > yydef_tbl->td_data = yydef_data = > calloc(yydef_tbl->td_lolen, sizeof(flex_int32_t)); > + if (yydef_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > for (i = 1; i <= total_states; ++i) { > mkdata(def[i]); > yydef_data[i] = def[i]; > @@ -1404,12 +1443,16 @@ gentabs() > (total_states >= INT16_MAX > || long_align) ? "flex_int32_t" : "flex_int16_t"); > > yynxt_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yynxt_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yynxt_tbl, YYTD_ID_NXT); > yynxt_tbl->td_lolen = tblend + 1; > yynxt_tbl->td_data = yynxt_data = > calloc(yynxt_tbl->td_lolen, sizeof(flex_int32_t)); > + if (yynxt_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > for (i = 1; i <= tblend; ++i) { > /* > * Note, the order of the following test is important. If > @@ -1442,12 +1485,16 @@ gentabs() > (total_states >= INT16_MAX > || long_align) ? "flex_int32_t" : "flex_int16_t"); > > yychk_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yychk_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yychk_tbl, YYTD_ID_CHK); > yychk_tbl->td_lolen = tblend + 1; > yychk_tbl->td_data = yychk_data = > calloc(yychk_tbl->td_lolen, sizeof(flex_int32_t)); > + if (yychk_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > for (i = 1; i <= tblend; ++i) { > if (chk[i] == 0) > ++nummt; > @@ -1703,15 +1750,19 @@ make_tables() > (fullspd) ? "struct yy_trans_info*" : > "flex_int32_t"); > > yynultrans_tbl = calloc(1, sizeof(struct yytbl_data)); > + if (yynultrans_tbl == NULL) > + flexerror(_("calloc failed")); > yytbl_data_init(yynultrans_tbl, YYTD_ID_NUL_TRANS); > if (fullspd) > yynultrans_tbl->td_flags |= YYTD_PTRANS; > yynultrans_tbl->td_lolen = lastdfa + 1; > yynultrans_tbl->td_data = yynultrans_data = > calloc(yynultrans_tbl->td_lolen, > sizeof(flex_int32_t)); > + if (yynultrans_tbl->td_data == NULL) > + flexerror(_("calloc failed")); > > for (i = 1; i <= lastdfa; ++i) { > if (fullspd) { > out_dec(" &yy_transition[%d],\n", > Index: main.c > =================================================================== > RCS file: /cvs/src/usr.bin/lex/main.c,v > retrieving revision 1.27 > diff -u -p -U4 -r1.27 main.c > --- main.c 21 Jan 2017 08:33:07 -0000 1.27 > +++ main.c 25 Aug 2019 12:09:55 -0000 > @@ -382,8 +382,10 @@ check_options() > > if (!tablesfilename) { > nbytes = strlen(prefix) + strlen(tablesfile_template) + > 2; > tablesfilename = pname = (char *) calloc(nbytes, 1); > + if (tablesfilename == NULL) > + flexerror(_("calloc failed")); > snprintf(pname, nbytes, tablesfile_template, prefix); > } > if ((tablesout = fopen(tablesfilename, "w")) == NULL) > lerrsf(_("could not create %s"), tablesfilename); > @@ -393,8 +395,10 @@ check_options() > yytbl_writer_init(&tableswr, tablesout); > > nbytes = strlen(prefix) + strlen("tables") + 2; > tablesname = (char *) calloc(nbytes, 1); > + if (tablesname == NULL) > + flexerror(_("calloc failed")); > snprintf(tablesname, nbytes, "%stables", prefix); > yytbl_hdr_init(&hdr, flex_version, tablesname); > > if (yytbl_hdr_fwrite(&tableswr, &hdr) <= 0) > Index: scanopt.c > =================================================================== > RCS file: /cvs/src/usr.bin/lex/scanopt.c,v > retrieving revision 1.6 > diff -u -p -U4 -r1.6 scanopt.c > --- scanopt.c 31 May 2017 07:20:26 -0000 1.6 > +++ scanopt.c 25 Aug 2019 12:09:57 -0000 > @@ -169,8 +169,10 @@ scanopt_t *scanopt_init (options, argc, > { > int i; > struct _scanopt_t *s; > s = (struct _scanopt_t *) malloc (sizeof (struct _scanopt_t)); > + if (s == NULL) > + flexerror(_("malloc failed")); > > s->options = options; > s->optc = 0; > s->argc = argc; > @@ -188,8 +190,10 @@ scanopt_t *scanopt_init (options, argc, > s->optc++; > > /* Build auxiliary data */ > s->aux = (struct _aux *) malloc (s->optc * sizeof (struct _aux)); > + if (s->aux == NULL) > + flexerror(_("malloc failed")); > > for (i = 0; i < s->optc; i++) { > const u_char *p, *pname; > const struct optspec_t *opt; > @@ -295,8 +299,10 @@ int scanopt_usage (scanner, fp, usag > fprintf (fp, "\n"); > > /* Sort by r_val and string. Yes, this is O(n*n), but n is small. */ > store = (usg_elem *) malloc (s->optc * sizeof (usg_elem)); > + if (store == NULL) > + flexerror(_("malloc failed")); > for (i = 0; i < s->optc; i++) { > > /* grab the next preallocate node. */ > ue = store + store_idx++; > Index: tables.c > =================================================================== > RCS file: /cvs/src/usr.bin/lex/tables.c,v > retrieving revision 1.4 > diff -u -p -U4 -r1.4 tables.c > --- tables.c 17 Aug 2017 19:27:09 -0000 1.4 > +++ tables.c 25 Aug 2019 12:09:58 -0000 > @@ -439,8 +439,10 @@ void yytbl_data_compress (struct yytbl_d > } > > total_len = yytbl_calc_total_len (tbl); > newtbl.td_data = calloc (total_len, newsz); > + if (newtbl.td_data == NULL) > + flexerror(_("calloc failed")); > newtbl.td_flags = > TFLAGS_CLRDATA (newtbl.td_flags) | BYTES2TFLAG (newsz); > > for (i = 0; i < total_len; i++) { >