flex {c,m}alloc() checks

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

flex {c,m}alloc() checks

Michael Mikonos
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?

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

Reply | Threaded
Open this post in threaded view
|

Re: flex {c,m}alloc() checks

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

Reply | Threaded
Open this post in threaded view
|

Re: flex {c,m}alloc() checks

Michael Mikonos
On Sun, Aug 25, 2019 at 02:58:47PM +0200, Otto Moerbeek wrote:

> 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).

Upstream has the _() macro and also calls flexerror() on allocation
failure. To me it is also nicer adding an xmalloc/xcalloc.
That would be a bigger patch though as the calls currently
checking malloc/calloc return value get modified too.

- Michael

Reply | Threaded
Open this post in threaded view
|

Re: flex {c,m}alloc() checks

Otto Moerbeek
On Wed, Aug 28, 2019 at 10:07:32AM +0800, Michael Mikonos wrote:

> On Sun, Aug 25, 2019 at 02:58:47PM +0200, Otto Moerbeek wrote:
> > 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).
>
> Upstream has the _() macro and also calls flexerror() on allocation
> failure. To me it is also nicer adding an xmalloc/xcalloc.
> That would be a bigger patch though as the calls currently
> checking malloc/calloc return value get modified too.
>
> - Michael
>

I'd say go for the x* solution,

        -Otto

Reply | Threaded
Open this post in threaded view
|

Re: flex {c,m}alloc() checks

Michael Mikonos
> I'd say go for the x* solution,
>
> -Otto

Sure. When I looked at this again there are also realloc() return
value checks missing, so I added xcalloc(), xmalloc() and xrealloc().
An old (unused) function yy_flex_xmalloc() gets removed. When building
this I checked the resulting .o files using nm(1) to make sure I didn't
miss any direct calls to calloc/malloc/realloc. However, scan.o and
parse.o were left alone. Does this look better?


Index: flexdef.h
===================================================================
RCS file: /cvs/src/usr.bin/lex/flexdef.h,v
retrieving revision 1.15
diff -u -r1.15 flexdef.h
--- flexdef.h 19 Nov 2015 23:48:06 -0000 1.15
+++ flexdef.h 28 Aug 2019 13:23:15 -0000
@@ -920,8 +920,9 @@
 /* Output a yy_trans_info structure. */
 extern void transition_struct_out PROTO ((int, int));
 
-/* Only needed when using certain broken versions of bison to build parse.c. */
-extern void *yy_flex_xmalloc PROTO ((int));
+extern void *xmalloc PROTO ((size_t));
+extern void *xcalloc PROTO ((size_t, size_t));
+extern void *xrealloc PROTO ((void *, size_t));
 
 /* from file nfa.c */
 
Index: buf.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/buf.c,v
retrieving revision 1.7
diff -u -r1.7 buf.c
--- buf.c 20 Nov 2015 18:54:49 -0000 1.7
+++ buf.c 28 Aug 2019 13:23:15 -0000
@@ -79,9 +79,7 @@
  size_t tsz;
 
  tsz = strlen(fmt) + strlen(s) + 1;
- t = malloc(tsz);
- if (!t)
- flexfatal(_("Allocation of buffer to print string failed"));
+ t = xmalloc(tsz);
  snprintf(t, tsz, fmt, s);
  buf = buf_strappend(buf, t);
  free(t);
@@ -105,9 +103,7 @@
     2 * strlen(filename) + /* filename with possibly all backslashes escaped */
     (int) (1 + log10(abs(lineno))) + /* line number */
     1; /* NUL */
- t = malloc(tsz);
- if (!t)
- flexfatal(_("Allocation of buffer for line directive failed"));
+ t = xmalloc(tsz);
  dst = t + snprintf(t, tsz, "#line %d \"", lineno);
  for (src = filename; *src; *dst++ = *src++)
  if (*src == '\\') /* escape backslashes */
@@ -181,10 +177,7 @@
 
  val = val ? val : "";
  strsz = strlen(fmt) + strlen(def) + strlen(val) + 2;
- str = malloc(strsz);
- if (!str)
- flexfatal(_("Allocation of buffer for m4 def failed"));
-
+ str = xmalloc(strsz);
  snprintf(str, strsz, fmt, def, val);
  buf_append(buf, &str, 1);
  return buf;
@@ -203,10 +196,7 @@
  size_t strsz;
 
  strsz = strlen(fmt) + strlen(def) + 2;
- str = malloc(strsz);
- if (!str)
- flexfatal(_("Allocation of buffer for m4 undef failed"));
-
+ str = xmalloc(strsz);
  snprintf(str, strsz, fmt, def);
  buf_append(buf, &str, 1);
  return buf;
Index: dfa.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/dfa.c,v
retrieving revision 1.8
diff -u -r1.8 dfa.c
--- dfa.c 19 Nov 2015 23:20:34 -0000 1.8
+++ dfa.c 28 Aug 2019 13:23:15 -0000
@@ -523,15 +523,12 @@
  * So we'll have to realloc() on the way...
  * we'll wait until we can calculate yynxt_tbl->td_hilen.
  */
- yynxt_tbl =
- (struct yytbl_data *) calloc (1,
-      sizeof (struct
-      yytbl_data));
+ yynxt_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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 *
+ xcalloc(yynxt_tbl->td_lolen *
     yynxt_tbl->td_hilen,
     sizeof (flex_int32_t));
  yynxt_curr = 0;
@@ -715,7 +712,7 @@
  /* Each time we hit here, it's another td_hilen, so we realloc. */
  yynxt_tbl->td_hilen++;
  yynxt_tbl->td_data = yynxt_data =
- (flex_int32_t *) realloc (yynxt_data,
+ xrealloc(yynxt_data,
      yynxt_tbl->td_hilen *
      yynxt_tbl->td_lolen *
      sizeof (flex_int32_t));
Index: filter.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/filter.c,v
retrieving revision 1.9
diff -u -r1.9 filter.c
--- filter.c 30 Aug 2017 02:54:07 -0000 1.9
+++ filter.c 28 Aug 2019 13:23:15 -0000
@@ -50,9 +50,7 @@
  va_list ap;
 
  /* allocate and initialize new filter */
- f = calloc(sizeof(struct filter), 1);
- if (!f)
- flexerror(_("calloc failed (f) in filter_create_ext"));
+ f = xcalloc(sizeof(struct filter), 1);
  f->filter_func = NULL;
  f->extra = NULL;
  f->next = NULL;
@@ -66,16 +64,14 @@
  }
  /* allocate argv, and populate it with the argument list. */
  max_args = 8;
- f->argv = malloc(sizeof(char *) * (max_args + 1));
- if (!f->argv)
- flexerror(_("malloc failed (f->argv) in filter_create_ext"));
+ f->argv = xmalloc(sizeof(char *) * (max_args + 1));
  f->argv[f->argc++] = cmd;
 
  va_start(ap, cmd);
  while ((s = va_arg(ap, const char *)) != NULL) {
  if (f->argc >= max_args) {
  max_args += 8;
- f->argv = realloc(f->argv,
+ f->argv = xrealloc(f->argv,
     sizeof(char *) * (max_args + 1));
  }
  f->argv[f->argc++] = s;
@@ -102,9 +98,7 @@
  struct filter *f;
 
  /* allocate and initialize new filter */
- f = calloc(sizeof(struct filter), 1);
- if (!f)
- flexerror(_("calloc failed in filter_create_int"));
+ f = xcalloc(sizeof(struct filter), 1);
  f->next = NULL;
  f->argc = 0;
  f->argv = NULL;
@@ -285,9 +279,7 @@
  fprintf(to_c, "m4_define( [[M4_YY_OUTFILE_NAME]],[[%s]])m4_dnl\n",
     outfilename ? outfilename : "<stdout>");
 
- buf = malloc(readsz);
- if (!buf)
- flexerror(_("malloc failed in filter_tee_header"));
+ buf = xmalloc(readsz);
  while (fgets(buf, readsz, stdin)) {
  fputs(buf, to_c);
  if (write_header)
@@ -349,9 +341,7 @@
  if (!chain)
  return 0;
 
- buf = malloc(readsz);
- if (!buf)
- flexerror(_("malloc failed in filter_fix_linedirs"));
+ buf = xmalloc(readsz);
 
  while (fgets(buf, readsz, stdin)) {
 
Index: gen.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/gen.c,v
retrieving revision 1.15
diff -u -r1.15 gen.c
--- gen.c 19 Nov 2015 23:28:03 -0000 1.15
+++ gen.c 28 Aug 2019 13:23:16 -0000
@@ -111,12 +111,12 @@
  flex_int8_t *tdata = NULL;
  struct yytbl_data *tbl;
 
- tbl = calloc(1, sizeof(struct yytbl_data));
+ tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(tbl->td_lolen, sizeof(flex_int8_t));
 
  for (i = 1; i <= num_rules; i++)
  tdata[i] = rule_has_nl[i] ? 1 : 0;
@@ -223,14 +223,14 @@
     ((tblend + numecs + 1) >= INT16_MAX
  || long_align) ? "flex_int32_t" : "flex_int16_t");
 
- tbl = calloc(1, sizeof(struct yytbl_data));
+ tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(tbl->td_lolen * 2, sizeof(flex_int32_t));
 
  /*
  * We want the transition to be represented as the offset to the next
@@ -318,14 +318,14 @@
  flex_int32_t *tdata = NULL;
  flex_int32_t i;
 
- tbl = calloc(1, sizeof(struct yytbl_data));
+ tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(tbl->td_lolen, sizeof(flex_int32_t));
 
  for (i = 0; i <= lastsc * 2; ++i)
  tdata[i] = base[i];
@@ -452,14 +452,14 @@
  struct yytbl_data *tbl = NULL;
  flex_int32_t *tdata = NULL;
 
- tbl = calloc(1, sizeof(struct yytbl_data));
+ tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(tbl->td_lolen, sizeof(flex_int32_t));
 
  for (i = 1; i < csize; ++i) {
  ecgroup[i] = ABS(ecgroup[i]);
@@ -659,14 +659,14 @@
  struct yytbl_data *tbl;
  flex_int32_t *tdata = NULL;
 
- tbl = calloc(1, sizeof(struct yytbl_data));
+ tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(tbl->td_lolen, sizeof(flex_int32_t));
 
  dfaacc[end_of_buffer_state].dfaacc_state = end_of_buffer_action;
 
@@ -1102,11 +1102,11 @@
     "\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));
+ yyacclist_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(yyacclist_tbl->td_lolen, sizeof(flex_int32_t));
  yyacclist_curr = 1;
 
  j = 1; /* index into "yy_acclist" array */
@@ -1212,11 +1212,11 @@
     "\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));
+ yyacc_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(yyacc_tbl->td_lolen, sizeof(flex_int32_t));
  yyacc_curr = 1;
 
  for (i = 1; i <= lastdfa; ++i) {
@@ -1268,11 +1268,11 @@
  * templates with).
  */
  flex_int32_t *yymecs_data = NULL;
- yymeta_tbl = calloc(1, sizeof(struct yytbl_data));
+ yymeta_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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,
+    xcalloc(yymeta_tbl->td_lolen,
     sizeof(flex_int32_t));
 
  if (trace)
@@ -1315,11 +1315,11 @@
     "\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));
+ yybase_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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,
+    xcalloc(yybase_tbl->td_lolen,
     sizeof(flex_int32_t));
  yybase_curr = 1;
 
@@ -1372,11 +1372,11 @@
     (total_states >= INT16_MAX
  || long_align) ? "flex_int32_t" : "flex_int16_t");
 
- yydef_tbl = calloc(1, sizeof(struct yytbl_data));
+ yydef_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(yydef_tbl->td_lolen, sizeof(flex_int32_t));
 
  for (i = 1; i <= total_states; ++i) {
  mkdata(def[i]);
@@ -1404,11 +1404,11 @@
     (total_states >= INT16_MAX
  || long_align) ? "flex_int32_t" : "flex_int16_t");
 
- yynxt_tbl = calloc(1, sizeof(struct yytbl_data));
+ yynxt_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(yynxt_tbl->td_lolen, sizeof(flex_int32_t));
 
  for (i = 1; i <= tblend; ++i) {
  /*
@@ -1442,11 +1442,11 @@
     (total_states >= INT16_MAX
  || long_align) ? "flex_int32_t" : "flex_int16_t");
 
- yychk_tbl = calloc(1, sizeof(struct yytbl_data));
+ yychk_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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));
+    xcalloc(yychk_tbl->td_lolen, sizeof(flex_int32_t));
 
  for (i = 1; i <= tblend; ++i) {
  if (chk[i] == 0)
@@ -1703,13 +1703,13 @@
     (fullspd) ? "struct yy_trans_info*" :
     "flex_int32_t");
 
- yynultrans_tbl = calloc(1, sizeof(struct yytbl_data));
+ yynultrans_tbl = xcalloc(1, sizeof(struct yytbl_data));
  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,
+    xcalloc(yynultrans_tbl->td_lolen,
     sizeof(flex_int32_t));
 
  for (i = 1; i <= lastdfa; ++i) {
Index: main.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/main.c,v
retrieving revision 1.27
diff -u -r1.27 main.c
--- main.c 21 Jan 2017 08:33:07 -0000 1.27
+++ main.c 28 Aug 2019 13:23:16 -0000
@@ -382,7 +382,7 @@
 
  if (!tablesfilename) {
  nbytes = strlen(prefix) + strlen(tablesfile_template) + 2;
- tablesfilename = pname = (char *) calloc(nbytes, 1);
+ tablesfilename = pname = xcalloc(nbytes, 1);
  snprintf(pname, nbytes, tablesfile_template, prefix);
  }
  if ((tablesout = fopen(tablesfilename, "w")) == NULL)
@@ -393,7 +393,7 @@
  yytbl_writer_init(&tableswr, tablesout);
 
  nbytes = strlen(prefix) + strlen("tables") + 2;
- tablesname = (char *) calloc(nbytes, 1);
+ tablesname = xcalloc(nbytes, 1);
  snprintf(tablesname, nbytes, "%stables", prefix);
  yytbl_hdr_init(&hdr, flex_version, tablesname);
 
@@ -434,9 +434,8 @@
  char *str, *fmt = "#define %s %d\n";
  size_t strsz;
 
- str = (char *) malloc(strsz = strlen(fmt) + strlen(scname[i]) + (int) (1 + log10(i)) + 2);
- if (!str)
- flexfatal(_("allocation of macro definition failed"));
+ strsz = strlen(fmt) + strlen(scname[i]) + (int) (1 + log10(i)) + 2;
+ str = xmalloc(strsz);
  snprintf(str, strsz, fmt, scname[i], i - 1);
  buf_strappend(&tmpbuf, str);
  free(str);
Index: misc.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/misc.c,v
retrieving revision 1.19
diff -u -r1.19 misc.c
--- misc.c 19 Nov 2015 23:34:56 -0000 1.19
+++ misc.c 28 Aug 2019 13:23:16 -0000
@@ -63,14 +63,12 @@
 {
  if (!sko_stack) {
  sko_sz = 1;
- sko_stack = malloc(sizeof(struct sko_state) * sko_sz);
- if (!sko_stack)
- flexfatal(_("allocation of sko_stack failed"));
+ sko_stack = xmalloc(sizeof(struct sko_state) * sko_sz);
  sko_len = 0;
  }
  if (sko_len >= sko_sz) {
  sko_sz *= 2;
- sko_stack = realloc(sko_stack, sizeof(struct sko_state) * sko_sz);
+ sko_stack = xrealloc(sko_stack, sizeof(struct sko_state) * sko_sz);
  }
  /* initialize to zero and push */
  sko_stack[sko_len].dc = dc;
@@ -176,15 +174,9 @@
  int size;
  size_t element_size;
 {
- void *mem;
  size_t num_bytes = element_size * size;
 
- mem = malloc(num_bytes);
- if (!mem)
- flexfatal(_
-    ("memory allocation failed in allocate_array()"));
-
- return mem;
+ return (xmalloc(num_bytes));
 }
 
 
@@ -275,11 +267,7 @@
  for (c1 = str; *c1; ++c1);
 
  size = (c1 - str + 1) * sizeof(char);
-
- copy = (char *) malloc(size);
-
- if (copy == NULL)
- flexfatal(_("dynamic memory failure in copy_string()"));
+ copy = xmalloc(size);
 
  for (c2 = copy; (*c2++ = *str++) != 0;);
 
@@ -836,14 +824,9 @@
  int size;
  size_t element_size;
 {
- void *new_array;
  size_t num_bytes = element_size * size;
 
- new_array = realloc(array, num_bytes);
- if (!new_array)
- flexfatal(_("attempt to increase array size failed"));
-
- return new_array;
+ return (xrealloc(array, num_bytes));
 }
 
 
@@ -991,21 +974,37 @@
  }
 }
 
+void *
+xmalloc(size_t size)
+{
+ void *p;
+
+ p = malloc(size);
+ if (p == NULL)
+ flexerror(_("malloc failed"));
+ return (p);
+}
 
-/* The following is only needed when building flex's parser using certain
- * broken versions of bison.
- */
 void *
-yy_flex_xmalloc(size)
- int size;
+xcalloc(size_t nmemb, size_t size)
 {
- void *result = malloc((size_t) size);
+ void *p;
 
- if (!result)
- flexfatal(_
-    ("memory allocation failed in yy_flex_xmalloc()"));
+ p = calloc(nmemb, size);
+ if (p == NULL)
+ flexerror(_("calloc failed"));
+ return (p);
+}
 
- return result;
+void *
+xrealloc(void *ptr, size_t size)
+{
+ void *p;
+
+ p = realloc(ptr, size);
+ if (p == NULL)
+ flexerror(_("realloc failed"));
+ return (p);
 }
 
 
Index: regex.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/regex.c,v
retrieving revision 1.3
diff -u -r1.3 regex.c
--- regex.c 19 Nov 2015 23:20:34 -0000 1.3
+++ regex.c 28 Aug 2019 13:23:17 -0000
@@ -59,12 +59,8 @@
         const int errbuf_sz = 200;
         char *errbuf, *rxerr;
 
- errbuf = (char*)malloc(errbuf_sz *sizeof(char));
- if (!errbuf)
- flexfatal(_("Unable to allocate buffer to report regcomp"));
- rxerr = (char*)malloc(errbuf_sz *sizeof(char));
- if (!rxerr)
- flexfatal(_("Unable to allocate buffer for regerror"));
+ errbuf = xmalloc(errbuf_sz * sizeof(char));
+ rxerr = xmalloc(errbuf_sz * sizeof(char));
  regerror (err, preg, rxerr, errbuf_sz);
  snprintf (errbuf, errbuf_sz, "regcomp for \"%s\" failed: %s", regex, rxerr);
 
@@ -87,9 +83,7 @@
  if (m == NULL || m->rm_so < 0)
  return NULL;
  len = m->rm_eo - m->rm_so;
- str = (char *) malloc ((len + 1) * sizeof (char));
- if (!str)
- flexfatal(_("Unable to allocate a copy of the match"));
+ str = xmalloc((len + 1) * sizeof(char));
  strncpy (str, src + m->rm_so, len);
  str[len] = 0;
  return str;
Index: scanflags.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/scanflags.c,v
retrieving revision 1.3
diff -u -r1.3 scanflags.c
--- scanflags.c 19 Nov 2015 23:20:34 -0000 1.3
+++ scanflags.c 28 Aug 2019 13:23:17 -0000
@@ -41,9 +41,10 @@
 void
 sf_push (void)
 {
-    if (_sf_top_ix + 1 >= _sf_max)
-        _sf_stk = (scanflags_t*) realloc ( (void*) _sf_stk, sizeof(scanflags_t) * (_sf_max += 32));
-
+    if (_sf_top_ix + 1 >= _sf_max) {
+        _sf_max += 32;
+        _sf_stk = xrealloc(_sf_stk, sizeof(scanflags_t) * _sf_max);
+    }
     // copy the top element
     _sf_stk[_sf_top_ix + 1] = _sf_stk[_sf_top_ix];
     ++_sf_top_ix;
@@ -61,9 +62,7 @@
 sf_init (void)
 {
     assert(_sf_stk == NULL);
-    _sf_stk = (scanflags_t*) malloc ( sizeof(scanflags_t) * (_sf_max = 32));
-    if (!_sf_stk)
-        lerrsf_fatal(_("Unable to allocate %ld of stack"),
-            (void *)sizeof(scanflags_t));
+    _sf_max = 32;
+    _sf_stk = xmalloc(sizeof(scanflags_t) * _sf_max);
     _sf_stk[_sf_top_ix] = 0;
 }
Index: scanopt.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/scanopt.c,v
retrieving revision 1.6
diff -u -r1.6 scanopt.c
--- scanopt.c 31 May 2017 07:20:26 -0000 1.6
+++ scanopt.c 28 Aug 2019 13:23:17 -0000
@@ -169,8 +169,8 @@
 {
  int     i;
  struct _scanopt_t *s;
- s = (struct _scanopt_t *) malloc (sizeof (struct _scanopt_t));
 
+ s = xmalloc(sizeof(struct _scanopt_t));
  s->options = options;
  s->optc = 0;
  s->argc = argc;
@@ -188,7 +188,7 @@
  s->optc++;
 
  /* Build auxiliary data */
- s->aux = (struct _aux *) malloc (s->optc * sizeof (struct _aux));
+ s->aux = xmalloc(s->optc * sizeof(struct _aux));
 
  for (i = 0; i < s->optc; i++) {
  const u_char *p, *pname;
@@ -295,7 +295,7 @@
  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));
+ store = xmalloc(s->optc * sizeof(usg_elem));
  for (i = 0; i < s->optc; i++) {
 
  /* grab the next preallocate node. */
Index: sym.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/sym.c,v
retrieving revision 1.9
diff -u -r1.9 sym.c
--- sym.c 19 Nov 2015 23:34:56 -0000 1.9
+++ sym.c 28 Aug 2019 13:23:17 -0000
@@ -95,11 +95,7 @@
  }
 
  /* create new entry */
- new_entry = (struct hash_entry *)
- malloc (sizeof (struct hash_entry));
-
- if (new_entry == NULL)
- flexfatal (_("symbol table memory allocation failed"));
+ new_entry = xmalloc(sizeof(struct hash_entry));
 
  if ((successor = table[hash_val]) != 0) {
  new_entry->next = successor;
Index: tables.c
===================================================================
RCS file: /cvs/src/usr.bin/lex/tables.c,v
retrieving revision 1.4
diff -u -r1.4 tables.c
--- tables.c 17 Aug 2017 19:27:09 -0000 1.4
+++ tables.c 28 Aug 2019 13:23:17 -0000
@@ -439,7 +439,7 @@
  }
 
  total_len = yytbl_calc_total_len (tbl);
- newtbl.td_data = calloc (total_len, newsz);
+ newtbl.td_data = xcalloc(total_len, newsz);
  newtbl.td_flags =
  TFLAGS_CLRDATA (newtbl.td_flags) | BYTES2TFLAG (newsz);