> Am 01.03.2025 um 09:59 schrieb Jakub Jelinek <ja...@redhat.com>:
> 
> Hi!
> 
> As the comment in check_line says:
>  /* get_buffer is not null terminated, but the sscanf stops after a number.  
> */
> the buffer is not null terminated, there is line.length () to determine
> the size of the line.  But unlike what the comment says, sscanf actually
> still requires null terminated string argument, anything else is UB.
> E.g. glibc when initializing the temporary FILE stream for the string does
>  if (size == 0)
>    end = strchr (ptr, '\0');
> and this strchr/rawmemchr is what shows up in valgrind report on cc1/cc1plus
> doing self-tests.
> 
> The function is used only in a test with 1000 lines, each containg its
> number, so numbers from 1 to 1000 inclusive (each time with '\n' separator,
> but that isn't included in line.length ()).
> 
> So the function just uses a temporary buffer which can fit numbers from 1 to
> 1000 as strings with terminating '\0' and runs sscanf on that (why not
> strtoul?).
> 
> Furthermore, the caller allocated number of lines * 15 bytes for the
> string, but 1000\n is 5 bytes, so I think * 5 is more than enough.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok

Richard 

> 2025-02-28  Jakub Jelinek  <ja...@redhat.com>
> 
>    PR other/119052
>    * input.cc (check_line): Don't call sscanf on non-null terminated
>    buffer, instead copy line.length () bytes from line.get_buffer ()
>    to a local buffer, null terminate it and call sscanf on that.
>    Formatting fix.
>    (test_replacement): Just allocate maxline * 5 rather than maxline * 15
>    bytes for the file.  Formatting fix.
> 
> --- gcc/input.cc.jj    2025-02-27 22:10:39.140082904 +0100
> +++ gcc/input.cc    2025-02-28 16:31:21.731021115 +0100
> @@ -2361,22 +2361,29 @@ test_make_location_nonpure_range_endpoin
> 
> /* Verify reading of a specific line LINENUM in TMP, FC.  */
> 
> -static void check_line (temp_source_file &tmp, file_cache &fc, int linenum)
> +static void
> +check_line (temp_source_file &tmp, file_cache &fc, int linenum)
> {
>   char_span line = fc.get_source_line (tmp.get_filename (), linenum);
>   int n;
> -  /* get_buffer is not null terminated, but the sscanf stops after a number. 
>  */
> -  ASSERT_TRUE (sscanf (line.get_buffer (), "%d", &n) == 1);
> +  const char *b = line.get_buffer ();
> +  size_t l = line.length ();
> +  char buf[5];
> +  ASSERT_LT (l, 5);
> +  memcpy (buf, b, l);
> +  buf[l] = '\0';
> +  ASSERT_TRUE (sscanf (buf, "%d", &n) == 1);
>   ASSERT_EQ (n, linenum);
> }
> 
> /* Test file cache replacement.  */
> 
> -static void test_replacement ()
> +static void
> +test_replacement ()
> {
>   const int maxline = 1000;
> 
> -  char *vec = XNEWVEC (char, maxline * 15);
> +  char *vec = XNEWVEC (char, maxline * 5);
>   char *p = vec;
>   int i;
>   for (i = 1; i <= maxline; i++)
> 
>    Jakub
> 

Reply via email to