In my last PPH change, I eliminated the redundancy in the preprocessor
identifier lookaside table by removing the name of the identifier from
the head of the macro value.  This later led to a buffer overrun in
libcpp/symtab.c cpp_lt_replay.  The buffer was allocated based on the
value string size, which is was no longer large enough to hold the
definition string.

Split cpp_idents_used::max_length and cpp_lookaside::max_length into
max_ident_len and max_value_len.  In cpp_lt_replay, allocate the
buffer based on the sum of max_ident_len and max_value_len.

-- 
Lawrence Crowl

Attachment: src.change
Description: Binary data

Index: gcc/cp/pph.c
===================================================================
*** gcc/cp/pph.c	(revision 170837)
--- gcc/cp/pph.c	(working copy)
*************** pth_dump_identifiers (FILE *stream, cpp_
*** 502,509 ****
  {
    unsigned int idx, col = 1;
  
!   fprintf (stream, "%u identifiers up to %u chars\n",
!            identifiers->num_entries, identifiers->max_length);
    for (idx = 0; idx < identifiers->num_entries; ++idx)
      {
        cpp_ident_use *ident = identifiers->entries + idx;
--- 502,510 ----
  {
    unsigned int idx, col = 1;
  
!   fprintf (stream, "%u identifiers up to %u chars, vals to %u chars\n",
!            identifiers->num_entries, identifiers->max_ident_len,
!            identifiers->max_value_len);
    for (idx = 0; idx < identifiers->num_entries; ++idx)
      {
        cpp_ident_use *ident = identifiers->entries + idx;
*************** pth_save_identifiers (cpp_idents_used *i
*** 793,814 ****
    unsigned int num_entries, id;
  
    num_entries = identifiers->num_entries;
!   pph_output_uint (stream, identifiers->max_length);
    pph_output_uint (stream, num_entries);
  
    for ( id = 0; id < num_entries; ++id )
      {
        cpp_ident_use *entry = identifiers->entries + id;
  
!       gcc_assert (entry->ident_len <= identifiers->max_length);
        pph_output_string_with_length (stream, entry->ident_str,
  				     entry->ident_len);
  
!       gcc_assert (entry->before_len <= identifiers->max_length);
        pph_output_string_with_length (stream, entry->before_str,
  				     entry->before_len);
  
!       gcc_assert (entry->after_len <= identifiers->max_length);
        pph_output_string_with_length (stream, entry->after_str,
  				     entry->after_len);
      }
--- 794,816 ----
    unsigned int num_entries, id;
  
    num_entries = identifiers->num_entries;
!   pph_output_uint (stream, identifiers->max_ident_len);
!   pph_output_uint (stream, identifiers->max_value_len);
    pph_output_uint (stream, num_entries);
  
    for ( id = 0; id < num_entries; ++id )
      {
        cpp_ident_use *entry = identifiers->entries + id;
  
!       gcc_assert (entry->ident_len <= identifiers->max_ident_len);
        pph_output_string_with_length (stream, entry->ident_str,
  				     entry->ident_len);
  
!       gcc_assert (entry->before_len <= identifiers->max_value_len);
        pph_output_string_with_length (stream, entry->before_str,
  				     entry->before_len);
  
!       gcc_assert (entry->after_len <= identifiers->max_value_len);
        pph_output_string_with_length (stream, entry->after_str,
  				     entry->after_len);
      }
*************** static void
*** 1025,1035 ****
  pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream)
  {
    unsigned int j;
!   unsigned int max_length, num_entries;
    unsigned int ident_len, before_len, after_len;
  
!   max_length = pph_input_uint (stream);
!   identifiers->max_length = max_length;
    num_entries = pph_input_uint (stream);
    identifiers->num_entries = num_entries;
    identifiers->entries = XCNEWVEC (cpp_ident_use, num_entries);
--- 1027,1039 ----
  pth_load_identifiers (cpp_idents_used *identifiers, pph_stream *stream)
  {
    unsigned int j;
!   unsigned int max_ident_len, max_value_len, num_entries;
    unsigned int ident_len, before_len, after_len;
  
!   max_ident_len = pph_input_uint (stream);
!   identifiers->max_ident_len = max_ident_len;
!   max_value_len = pph_input_uint (stream);
!   identifiers->max_value_len = max_value_len;
    num_entries = pph_input_uint (stream);
    identifiers->num_entries = num_entries;
    identifiers->entries = XCNEWVEC (cpp_ident_use, num_entries);
Index: libcpp/symtab.c
===================================================================
*** libcpp/symtab.c	(revision 170837)
--- libcpp/symtab.c	(working copy)
*************** cpp_lt_create (unsigned int order, unsig
*** 411,417 ****
    table->sticky_order = order;
    table->active = 0;
  
!   table->max_length = 0;
    table->strings = XCNEW (struct obstack);
    /* Strings need no alignment.  */
    _obstack_begin (table->strings, 0, 0,
--- 411,418 ----
    table->sticky_order = order;
    table->active = 0;
  
!   table->max_ident_len = 0;
!   table->max_value_len = 0;
    table->strings = XCNEW (struct obstack);
    /* Strings need no alignment.  */
    _obstack_begin (table->strings, 0, 0,
*************** lt_macro_value (const char** string, cpp
*** 556,563 ****
    const char *definition = lt_query_macro (reader, cpp_node);
    size_t macro_len = strlen (definition);
    *string = (const char *) obstack_copy0 (aside->strings, definition, macro_len);
!   if (macro_len > aside->max_length)
!     aside->max_length = macro_len;
    ++aside->macrovalue;
    return macro_len;
  }
--- 557,564 ----
    const char *definition = lt_query_macro (reader, cpp_node);
    size_t macro_len = strlen (definition);
    *string = (const char *) obstack_copy0 (aside->strings, definition, macro_len);
!   if (macro_len > aside->max_value_len)
!     aside->max_value_len = macro_len;
    ++aside->macrovalue;
    return macro_len;
  }
*************** cpp_lt_capture (cpp_reader *reader)
*** 606,612 ****
    /* Take the strings from the table and give to the summary.  */
    used.strings = aside->strings;
    aside->strings = NULL;
!   used.max_length = aside->max_length;
  
    aside->iterations += slots;
    ++aside->empties;
--- 607,614 ----
    /* Take the strings from the table and give to the summary.  */
    used.strings = aside->strings;
    aside->strings = NULL;
!   used.max_ident_len = aside->max_ident_len;
!   used.max_value_len = aside->max_value_len;
  
    aside->iterations += slots;
    ++aside->empties;
*************** cpp_lt_capture (cpp_reader *reader)
*** 635,641 ****
        aside->active = 0;
  
        /* Create a new string table.  */
!       aside->max_length = 0;
        aside->strings = XCNEW (struct obstack);
        /* Strings need no alignment.  */
        _obstack_begin (aside->strings, 0, 0,
--- 637,644 ----
        aside->active = 0;
  
        /* Create a new string table.  */
!       aside->max_ident_len = 0;
!       aside->max_value_len = 0;
        aside->strings = XCNEW (struct obstack);
        /* Strings need no alignment.  */
        _obstack_begin (aside->strings, 0, 0,
*************** cpp_lt_replay (cpp_reader *reader, cpp_i
*** 815,821 ****
    unsigned int i;
    unsigned int num_entries = identifiers->num_entries;
    cpp_ident_use *entries = identifiers->entries;
!   char *buffer = XCNEWVEC (char, identifiers->max_length + 1);
  
    /* Prevent the lexer from invalidating the tokens we've read so far.  */
    reader->keep_tokens++;
--- 818,825 ----
    unsigned int i;
    unsigned int num_entries = identifiers->num_entries;
    cpp_ident_use *entries = identifiers->entries;
!   char *buffer = XCNEWVEC (char, identifiers->max_ident_len
!                                  + identifiers->max_value_len + 1);
  
    /* Prevent the lexer from invalidating the tokens we've read so far.  */
    reader->keep_tokens++;
*************** lt_lookup (cpp_reader *reader,
*** 968,980 ****
    ++aside->active;
    entries[index].node = node;
    entries[index].hash = hash;
!   if (length > aside->max_length)
!     aside->max_length = length;
  
    /* Capture any macro value.  */
    if (cpp_node->type == NT_MACRO)
      entries[index].length = lt_macro_value
!             (&entries[index].value, aside, reader, cpp_node);
    /* else .value and .length are still zero from initialization.  */
  
    /* Check table load factor.  */
--- 972,984 ----
    ++aside->active;
    entries[index].node = node;
    entries[index].hash = hash;
!   if (length > aside->max_ident_len)
!     aside->max_ident_len = length;
  
    /* Capture any macro value.  */
    if (cpp_node->type == NT_MACRO)
      entries[index].length = lt_macro_value
!         (&entries[index].value, aside, reader, cpp_node);
    /* else .value and .length are still zero from initialization.  */
  
    /* Check table load factor.  */
Index: libcpp/include/symtab.h
===================================================================
*** libcpp/include/symtab.h	(revision 170837)
--- libcpp/include/symtab.h	(working copy)
*************** typedef struct GTY(()) cpp_ident_use
*** 120,126 ****
  
  typedef struct GTY(()) cpp_idents_used
  {
!   unsigned int max_length;
    unsigned int num_entries;
    cpp_ident_use *entries;
    struct obstack * GTY((skip)) strings;
--- 120,127 ----
  
  typedef struct GTY(()) cpp_idents_used
  {
!   unsigned int max_ident_len;
!   unsigned int max_value_len;
    unsigned int num_entries;
    cpp_ident_use *entries;
    struct obstack * GTY((skip)) strings;
Index: libcpp/internal.h
===================================================================
*** libcpp/internal.h	(revision 170837)
--- libcpp/internal.h	(working copy)
*************** struct cpp_lookaside {
*** 341,347 ****
    unsigned int sticky_order;	/* For resizing when capturing the entries.  */
    unsigned int active;		/* Number of active entries.  */
    struct obstack *strings;	/* For macro value storage.  */
!   unsigned int max_length;	/* Largest string encountered.  */
  
    /* Table usage statistics.  */
    unsigned long long searches;		/* Number of calls to lt_lookup.  */
--- 341,348 ----
    unsigned int sticky_order;	/* For resizing when capturing the entries.  */
    unsigned int active;		/* Number of active entries.  */
    struct obstack *strings;	/* For macro value storage.  */
!   unsigned int max_ident_len;	/* Largest identifier encountered.  */
!   unsigned int max_value_len;	/* Largest macro value encountered.  */
  
    /* Table usage statistics.  */
    unsigned long long searches;		/* Number of calls to lt_lookup.  */

Reply via email to