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++) {
>