bug-gnu-pspp
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

PSPP-BUG: [bug #54664] segfault in count_newlines in lexer.c


From: Tianxiao Gu
Subject: PSPP-BUG: [bug #54664] segfault in count_newlines in lexer.c
Date: Tue, 18 Sep 2018 19:40:52 -0400 (EDT)
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0

Follow-up Comment #1, bug #54664 (project pspp):

We found that token->token_len is used without initialization.

The struct `token` is created at line 1374.
By analyzing the code of `lex_push_token__`, we found that the memory of token
is allocated via `xnmalloc` in dequeu.c. So the memory may not be set to
zero.
Then, the following initialization code (line 1377, 1378, 1379, 1381, 1383)
does not set a proper value to `token->token_len`.
`token_len` is finally set to a proper value at 1457.

But in `lex_source_read__` (at line 1398), the toekn_len will be used during
reporting parsing error, which will lead to the crash.

1374   /* Append a new token to SRC and initialize it. */
1375   struct lex_token *token = lex_push_token__ (src);
1376   struct scanner scanner;
1377   scanner_init (&scanner, &token->token);
1378   token->line_pos = src->line_pos;
1379   token->token_pos = src->seg_pos;
1380   if (src->reader->line_number > 0)
1381     token->first_line = src->reader->line_number + src->n_newlines;
1382   else
1383     token->first_line = 0;
1384
1385   /* Extract segments and pass them through the scanner until we obtain
a
1386      token. */
1387   for (;;)
1388     {
1389       /* Extract a segment. */
1390       const char *segment = &src->buffer[state.seg_pos - src->tail];
1391       size_t seg_maxlen = src->head - state.seg_pos;
1392       enum segment_type type;
1393       int seg_len = segmenter_push (&state.segmenter, segment,
seg_maxlen,
1394                                     &type);
1395       if (seg_len < 0)
1396         {
1397           /* The segmenter needs more input to produce a segment. */
1398           lex_source_read__ (src);
1399           continue;
1400         }
1401     
1402       /* Update state based on the segment. */
1403       state.last_segment = type;
1404       state.seg_pos += seg_len;
1405       if (type == SEG_NEWLINE)
1406         {
1407           state.newlines++;
1408           state.line_pos = state.seg_pos;
1409         }
1410     
1411       /* Pass the segment into the scanner and try to get a token out.
*/
1412       enum scan_result result = scanner_push (&scanner, type,
1413                                               ss_buffer (segment,
seg_len),
1414                                               &token->token);
1415       if (result == SCAN_SAVE)
1416         saved = state;
1417       else if (result == SCAN_BACK)
1418         {
1419           state = saved;
1420           break;
1421         }
1422       else if (result == SCAN_DONE)
1423         break;
1424     }
1425
1426   /* If we've reached the end of a line, or the end of a command, then
pass
1427      the line to the output engine as a syntax text item.  */
1428   int n_lines = state.newlines;
1429   if (state.last_segment == SEG_END_COMMAND &&
!src->suppress_next_newline)
1430     {
1431       n_lines++;
1432       src->suppress_next_newline = true;
1433     }
1434   else if (n_lines > 0 && src->suppress_next_newline)
1435     {
1436       n_lines--;
1437       src->suppress_next_newline = false;
1438     }
1439   for (int i = 0; i < n_lines; i++)
1440     {
1441       const char *line = &src->buffer[src->journal_pos - src->tail];
1442       const char *newline = rawmemchr (line, '\n');
1443       size_t line_len = newline - line;
1444       if (line_len > 0 && line[line_len - 1] == '\r')
1445         line_len--;
1446
1447       char *syntax = malloc (line_len + 2);
1448       memcpy (syntax, line, line_len);
1449       syntax[line_len] = '\n';
1450       syntax[line_len + 1] = '\0';
1451
1452       text_item_submit (text_item_create_nocopy (TEXT_ITEM_SYNTAX,
syntax));
1453
1454       src->journal_pos += newline - line + 1;
1455     }
1456
1457   token->token_len = state.seg_pos - src->seg_pos;

    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?54664>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]