Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Richard Guenther
On Thu, Apr 19, 2012 at 12:42 PM, Jim Meyering j...@meyering.net wrote:
 Found by inspection.
 Seeing this strncpy use without the usual following NUL-termination,
 my reflex was that it was a buffer overrun candidate, but then I
 realized this is gcc, so that's not very likely.
 Looking a little harder, I saw the preceding strlen = sizeof buf test,
 which means there is no risk of overrun.

 That preceding test means the use of strncpy is misleading, since
 with that there is no risk of the name being too long for the buffer,
 and hence no reason to use strncpy.
 One way to make the code clearer is to use strcpy, as done below.
 An alternative is to use memcpy (buf, m-name, strlen (m-name) + 1).

 Ok to commit?

Without a comment before the strcpy this isn't any more clear than
when using strncpy.  Also your issue with the terminating NUL is
still present for the snprintf call done later (in fact the code looks like
it can be optimized, avoiding the strcpy in the path to the snprintf).

strncpy - strcpy definitely looks like premature optimization to me.

Richard.

 2012-04-19  Jim Meyering  meyer...@redhat.com

        genmodes: remove misleading use of strncpy
        * genmodes.c (make_complex_modes): Avoid unnecessary use of strncpy.
        We verified above that the string(including trailing NUL) fits in buf,
        so just use strcpy.


 diff --git a/gcc/genmodes.c b/gcc/genmodes.c
 index 8b6f5bc..f786258 100644
 --- a/gcc/genmodes.c
 +++ b/gcc/genmodes.c
 @@ -1,15 +1,15 @@
  /* Generate the machine mode enumeration and associated tables.
 -   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
 +   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2012
    Free Software Foundation, Inc.

  This file is part of GCC.

  GCC is free software; you can redistribute it and/or modify it under
  the terms of the GNU General Public License as published by the Free
  Software Foundation; either version 3, or (at your option) any later
  version.

  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  WARRANTY; without even the implied warranty of MERCHANTABILITY or
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  for more details.
 @@ -442,27 +442,27 @@ make_complex_modes (enum mode_class cl,
       if (strlen (m-name) = sizeof buf)
        {
          error (%s:%d:mode name \%s\ is too long,
                 m-file, m-line, m-name);
          continue;
        }

       /* Float complex modes are named SCmode, etc.
         Int complex modes are named CSImode, etc.
          This inconsistency should be eliminated.  */
       if (cl == MODE_FLOAT)
        {
          char *p, *q = 0;
 -         strncpy (buf, m-name, sizeof buf);
 +         strcpy (buf, m-name);
          p = strchr (buf, 'F');
          if (p == 0)
            q = strchr (buf, 'D');
          if (p == 0  q == 0)
            {
              error (%s:%d: float mode \%s\ has no 'F' or 'D',
                     m-file, m-line, m-name);
              continue;
            }

          if (p != 0)
            *p = 'C';
          else
 --
 1.7.10.208.gb4267


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Jakub Jelinek
On Thu, Apr 19, 2012 at 02:01:36PM +0200, Richard Guenther wrote:
 strncpy - strcpy definitely looks like premature optimization to me.

I disagree.  Almost all uses of strncpy are wrong.  If the string length is
smaller, than it is unlikely useful that it clears all remaining bytes
(sometimes many of them) - exception might be security sensitive code,
if the string length is known to be sizeof buf - 1, then strcpy or even
memcpy should be used, and if the string length is larger, then no '\0' is
appended, so it is unlikely the right thing.

Yes, Jim should probably add a comment.

Jakub


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Jim Meyering
Richard Guenther wrote:
 On Thu, Apr 19, 2012 at 12:42 PM, Jim Meyering j...@meyering.net wrote:
 Found by inspection.
 Seeing this strncpy use without the usual following NUL-termination,
 my reflex was that it was a buffer overrun candidate, but then I
 realized this is gcc, so that's not very likely.
 Looking a little harder, I saw the preceding strlen = sizeof buf test,
 which means there is no risk of overrun.

 That preceding test means the use of strncpy is misleading, since
 with that there is no risk of the name being too long for the buffer,
 and hence no reason to use strncpy.
 One way to make the code clearer is to use strcpy, as done below.
 An alternative is to use memcpy (buf, m-name, strlen (m-name) + 1).

Thanks for the quick feedback.

 Without a comment before the strcpy this isn't any more clear than

Good point.
How about with this folded in?

diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index f786258..3833017 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -452,6 +452,7 @@ make_complex_modes (enum mode_class cl,
   if (cl == MODE_FLOAT)
{
  char *p, *q = 0;
+ /* We verified above that m-name+NUL fits in buf.  */
  strcpy (buf, m-name);
  p = strchr (buf, 'F');
  if (p == 0)

 when using strncpy.  Also your issue with the terminating NUL is
 still present for the snprintf call done later (in fact the code looks like
 it can be optimized, avoiding the strcpy in the path to the snprintf).

Isn't it different with snprintf?
While strncpy does *NOT* necessarily NUL-terminate,
snprintf explicitly does, always.

IMHO, if you'd like to avoid the duplication in the strcpy/snprintf
path, that deserves to be a different change.


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Richard Guenther
On Thu, Apr 19, 2012 at 2:13 PM, Jim Meyering j...@meyering.net wrote:
 Richard Guenther wrote:
 On Thu, Apr 19, 2012 at 12:42 PM, Jim Meyering j...@meyering.net wrote:
 Found by inspection.
 Seeing this strncpy use without the usual following NUL-termination,
 my reflex was that it was a buffer overrun candidate, but then I
 realized this is gcc, so that's not very likely.
 Looking a little harder, I saw the preceding strlen = sizeof buf test,
 which means there is no risk of overrun.

 That preceding test means the use of strncpy is misleading, since
 with that there is no risk of the name being too long for the buffer,
 and hence no reason to use strncpy.
 One way to make the code clearer is to use strcpy, as done below.
 An alternative is to use memcpy (buf, m-name, strlen (m-name) + 1).

 Thanks for the quick feedback.

 Without a comment before the strcpy this isn't any more clear than

 Good point.
 How about with this folded in?

 diff --git a/gcc/genmodes.c b/gcc/genmodes.c
 index f786258..3833017 100644
 --- a/gcc/genmodes.c
 +++ b/gcc/genmodes.c
 @@ -452,6 +452,7 @@ make_complex_modes (enum mode_class cl,
       if (cl == MODE_FLOAT)
        {
          char *p, *q = 0;
 +         /* We verified above that m-name+NUL fits in buf.  */
          strcpy (buf, m-name);
          p = strchr (buf, 'F');
          if (p == 0)

That's better.  Or even cache the strlen result and use memcpy here
as Jakub suggested.

 when using strncpy.  Also your issue with the terminating NUL is
 still present for the snprintf call done later (in fact the code looks like
 it can be optimized, avoiding the strcpy in the path to the snprintf).

 Isn't it different with snprintf?
 While strncpy does *NOT* necessarily NUL-terminate,
 snprintf explicitly does, always.

Sure, my point was that the

  if (strlen (m-name) = sizeof buf)
{
  error (%s:%d:mode name \%s\ is too long,
 m-file, m-line, m-name);
  continue;
}

check does not account for the (conditional) prepending of 'C' and the
snprintf would silently discard the last character of the name.

 IMHO, if you'd like to avoid the duplication in the strcpy/snprintf
 path, that deserves to be a different change.

Sure.

The patch is ok with caching strlen and using memcpy.

Richard.


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Jakub Jelinek
On Thu, Apr 19, 2012 at 02:31:37PM +0200, Richard Guenther wrote:
 That's better.  Or even cache the strlen result and use memcpy here
 as Jakub suggested.

tree-ssa-strlen.c will do that for you when optimizing in this case ;)

Jakub


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Richard Guenther
On Thu, Apr 19, 2012 at 2:34 PM, Jakub Jelinek ja...@redhat.com wrote:
 On Thu, Apr 19, 2012 at 02:31:37PM +0200, Richard Guenther wrote:
 That's better.  Or even cache the strlen result and use memcpy here
 as Jakub suggested.

 tree-ssa-strlen.c will do that for you when optimizing in this case ;)

Does it?  But only if you used strcpy, no?

Richard.

        Jakub


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Jakub Jelinek
On Thu, Apr 19, 2012 at 02:38:11PM +0200, Richard Guenther wrote:
 On Thu, Apr 19, 2012 at 2:34 PM, Jakub Jelinek ja...@redhat.com wrote:
  On Thu, Apr 19, 2012 at 02:31:37PM +0200, Richard Guenther wrote:
  That's better.  Or even cache the strlen result and use memcpy here
  as Jakub suggested.
 
  tree-ssa-strlen.c will do that for you when optimizing in this case ;)
 
 Does it?  But only if you used strcpy, no?

Yes.  I don't think it would handle the strncpy, it is in that case not
about caching the value, but also additional comparison and knowing it is
sufficiently large.

Jakub


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Jim Meyering
Richard Guenther wrote:
 On Thu, Apr 19, 2012 at 2:13 PM, Jim Meyering j...@meyering.net wrote:
 Richard Guenther wrote:
 On Thu, Apr 19, 2012 at 12:42 PM, Jim Meyering j...@meyering.net wrote:
 Found by inspection.
 Seeing this strncpy use without the usual following NUL-termination,
 my reflex was that it was a buffer overrun candidate, but then I
 realized this is gcc, so that's not very likely.
 Looking a little harder, I saw the preceding strlen = sizeof buf test,
 which means there is no risk of overrun.

 That preceding test means the use of strncpy is misleading, since
 with that there is no risk of the name being too long for the buffer,
 and hence no reason to use strncpy.
 One way to make the code clearer is to use strcpy, as done below.
 An alternative is to use memcpy (buf, m-name, strlen (m-name) + 1).

 Thanks for the quick feedback.

 Without a comment before the strcpy this isn't any more clear than

 Good point.
 How about with this folded in?

 diff --git a/gcc/genmodes.c b/gcc/genmodes.c
 index f786258..3833017 100644
 --- a/gcc/genmodes.c
 +++ b/gcc/genmodes.c
 @@ -452,6 +452,7 @@ make_complex_modes (enum mode_class cl,
       if (cl == MODE_FLOAT)
        {
          char *p, *q = 0;
 +         /* We verified above that m-name+NUL fits in buf.  */
          strcpy (buf, m-name);
          p = strchr (buf, 'F');
          if (p == 0)

 That's better.  Or even cache the strlen result and use memcpy here
 as Jakub suggested.

 when using strncpy.  Also your issue with the terminating NUL is
 still present for the snprintf call done later (in fact the code looks like
 it can be optimized, avoiding the strcpy in the path to the snprintf).

 Isn't it different with snprintf?
 While strncpy does *NOT* necessarily NUL-terminate,
 snprintf explicitly does, always.

 Sure, my point was that the

   if (strlen (m-name) = sizeof buf)
 {
   error (%s:%d:mode name \%s\ is too long,
  m-file, m-line, m-name);
   continue;
 }

 check does not account for the (conditional) prepending of 'C' and the
 snprintf would silently discard the last character of the name.

Yes, you're right.
It's good to avoid snprintf and its truncation, too.

 IMHO, if you'd like to avoid the duplication in the strcpy/snprintf
 path, that deserves to be a different change.

 Sure.

 The patch is ok with caching strlen and using memcpy.

Like this, I presume:
[alternatively, declare and compute m_len on a separate line,
 just before the comparison:
   size_t m_len = strlen (m-name);
 I'd actually prefer that, but don't know if decl-after-stmt is ok here.
 ]

2012-04-19  Jim Meyering  meyer...@redhat.com

genmodes: remove misleading use of strncpy
* genmodes.c (make_complex_modes): Avoid unnecessary use of strncpy.
We verified above that the string(including trailing NUL) fits in buf,
so just use memcpy.

diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index 8b6f5bc..484a6ac 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -1,5 +1,5 @@
 /* Generate the machine mode enumeration and associated tables.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2012
Free Software Foundation, Inc.

 This file is part of GCC.
@@ -435,11 +435,13 @@ make_complex_modes (enum mode_class cl,

   for (m = modes[cl]; m; m = m-next)
 {
+  size_t m_len;
+
   /* Skip BImode.  FIXME: BImode probably shouldn't be MODE_INT.  */
   if (m-precision == 1)
continue;

-  if (strlen (m-name) = sizeof buf)
+  if ((m_len = strlen (m-name)) = sizeof buf)
{
  error (%s:%d:mode name \%s\ is too long,
 m-file, m-line, m-name);
@@ -452,7 +454,8 @@ make_complex_modes (enum mode_class cl,
   if (cl == MODE_FLOAT)
{
  char *p, *q = 0;
- strncpy (buf, m-name, sizeof buf);
+ /* We verified above that m-name+NUL fits in buf.  */
+ memcpy (buf, m-name, m_len + 1);
  p = strchr (buf, 'F');
  if (p == 0)
q = strchr (buf, 'D');
--
1.7.10.208.gb4267


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Richard Guenther
On Thu, Apr 19, 2012 at 3:01 PM, Jim Meyering j...@meyering.net wrote:
 Richard Guenther wrote:
 On Thu, Apr 19, 2012 at 2:13 PM, Jim Meyering j...@meyering.net wrote:
 Richard Guenther wrote:
 On Thu, Apr 19, 2012 at 12:42 PM, Jim Meyering j...@meyering.net wrote:
 Found by inspection.
 Seeing this strncpy use without the usual following NUL-termination,
 my reflex was that it was a buffer overrun candidate, but then I
 realized this is gcc, so that's not very likely.
 Looking a little harder, I saw the preceding strlen = sizeof buf test,
 which means there is no risk of overrun.

 That preceding test means the use of strncpy is misleading, since
 with that there is no risk of the name being too long for the buffer,
 and hence no reason to use strncpy.
 One way to make the code clearer is to use strcpy, as done below.
 An alternative is to use memcpy (buf, m-name, strlen (m-name) + 1).

 Thanks for the quick feedback.

 Without a comment before the strcpy this isn't any more clear than

 Good point.
 How about with this folded in?

 diff --git a/gcc/genmodes.c b/gcc/genmodes.c
 index f786258..3833017 100644
 --- a/gcc/genmodes.c
 +++ b/gcc/genmodes.c
 @@ -452,6 +452,7 @@ make_complex_modes (enum mode_class cl,
       if (cl == MODE_FLOAT)
        {
          char *p, *q = 0;
 +         /* We verified above that m-name+NUL fits in buf.  */
          strcpy (buf, m-name);
          p = strchr (buf, 'F');
          if (p == 0)

 That's better.  Or even cache the strlen result and use memcpy here
 as Jakub suggested.

 when using strncpy.  Also your issue with the terminating NUL is
 still present for the snprintf call done later (in fact the code looks like
 it can be optimized, avoiding the strcpy in the path to the snprintf).

 Isn't it different with snprintf?
 While strncpy does *NOT* necessarily NUL-terminate,
 snprintf explicitly does, always.

 Sure, my point was that the

       if (strlen (m-name) = sizeof buf)
         {
           error (%s:%d:mode name \%s\ is too long,
                  m-file, m-line, m-name);
           continue;
         }

 check does not account for the (conditional) prepending of 'C' and the
 snprintf would silently discard the last character of the name.

 Yes, you're right.
 It's good to avoid snprintf and its truncation, too.

 IMHO, if you'd like to avoid the duplication in the strcpy/snprintf
 path, that deserves to be a different change.

 Sure.

 The patch is ok with caching strlen and using memcpy.

 Like this, I presume:
 [alternatively, declare and compute m_len on a separate line,
  just before the comparison:
   size_t m_len = strlen (m-name);
  I'd actually prefer that, but don't know if decl-after-stmt is ok here.
  ]

Works for me with ...

 2012-04-19  Jim Meyering  meyer...@redhat.com

        genmodes: remove misleading use of strncpy
        * genmodes.c (make_complex_modes): Avoid unnecessary use of strncpy.
        We verified above that the string(including trailing NUL) fits in buf,
        so just use memcpy.

 diff --git a/gcc/genmodes.c b/gcc/genmodes.c
 index 8b6f5bc..484a6ac 100644
 --- a/gcc/genmodes.c
 +++ b/gcc/genmodes.c
 @@ -1,5 +1,5 @@
  /* Generate the machine mode enumeration and associated tables.
 -   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
 +   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2012
    Free Software Foundation, Inc.

  This file is part of GCC.
 @@ -435,11 +435,13 @@ make_complex_modes (enum mode_class cl,

   for (m = modes[cl]; m; m = m-next)
     {
 +      size_t m_len;
 +
       /* Skip BImode.  FIXME: BImode probably shouldn't be MODE_INT.  */
       if (m-precision == 1)
        continue;

 -      if (strlen (m-name) = sizeof buf)
 +      if ((m_len = strlen (m-name)) = sizeof buf)

... the strlen in a separate stmt like

m_len = strlen (m-name);
if (m_len = sizeof (buf))

Thanks,
Richard.

        {
          error (%s:%d:mode name \%s\ is too long,
                 m-file, m-line, m-name);
 @@ -452,7 +454,8 @@ make_complex_modes (enum mode_class cl,
       if (cl == MODE_FLOAT)
        {
          char *p, *q = 0;
 -         strncpy (buf, m-name, sizeof buf);
 +         /* We verified above that m-name+NUL fits in buf.  */
 +         memcpy (buf, m-name, m_len + 1);
          p = strchr (buf, 'F');
          if (p == 0)
            q = strchr (buf, 'D');
 --
 1.7.10.208.gb4267


Re: [PATCH] genmodes: remove misleading use of strncpy

2012-04-19 Thread Jim Meyering
Richard Guenther wrote:
...
 The patch is ok with caching strlen and using memcpy.

 Like this, I presume:
 [alternatively, declare and compute m_len on a separate line,
  just before the comparison:
   size_t m_len = strlen (m-name);
  I'd actually prefer that, but don't know if decl-after-stmt is ok here.
  ]

 Works for me with ...
...
 -      if (strlen (m-name) = sizeof buf)
 +      if ((m_len = strlen (m-name)) = sizeof buf)

 ... the strlen in a separate stmt like

 m_len = strlen (m-name);
 if (m_len = sizeof (buf))

Thanks.
Adjusted and committed.