octave-maintainers
[Top][All Lists]
Advanced

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

Re: C++ string::find functions and size_t


From: Daniel J Sebald
Subject: Re: C++ string::find functions and size_t
Date: Fri, 27 Feb 2015 18:42:22 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111108 Fedora/3.1.16-1.fc14 Thunderbird/3.1.16

On 02/27/2015 05:56 PM, John W. Eaton wrote:
On 02/27/2015 06:37 PM, Andreas Weber wrote:
Am 27.02.2015 um 18:47 schrieb rik:
2/27/15

Dan Sebald found a subtle bug in the use of the C++ string find
functions
that was leading to segfaults.

-- Code --
size_t pos = file.find_first_not_of ("|");
if (pos > 0)
file = file.substr (pos);
else
-- End Code --

I think the idea here was to check if the first char in file is "|" and
omit the check (because we are building a pipe) for an existent
directory in the else path.

The issue is that the size_t is an unsigned quantity and the find
functions
do not return -1 on failure as do regular C functions. Instead they
return
std::string::npos (a very large number) when they fail to find the
search term.

This was easily corrected to

-- Code --
size_t pos = file.find_first_not_of ("|");
if (pos != std::string::npos)
file = file.substr (pos);
else
-- End Code --

Please correct me if I'm wrong but shouldn't this then be

-- Code --
size_t pos = file.find_first_not_of ("|");
if (pos != std::string::npos && pos > 0)
-- End Code --

Yes, I think that's correct. I also thought maybe it would be clearer to
write if (file.length () > 0 && file[0] == '|'), then just extract get
file.substr (1) as the command. Shouldn't that work? It looks simpler to
me.

After thinking about it, a change there would be good. The logic associated with finding "anything but" makes the conditional a little unusual. I'm not sure even that is foolproof though. (If the user's not going to enter this string, then it doesn't matter I suppose.) What about cases like " | foo.out", if that is a possible user entry somehow. Maybe there should be:

  size_t pos = file.find_first_not_of (" ");
  if (pos != std::string::npos)
    {
      if (file[pos] == '|' && file.length () > (pos + 1) &&
          file.find_first_not_of (" ", ) != std::string::npos)
        {
          file = file.substr (pos);
        }
      else if (file[pos] != '|')
        {
          pos = file.find_last_of (file_ops::dir_sep_chars ());
          [etc]
        }
      else
        error[empty pipe spec, obviating "broken pipe" error]
    }
  else
    error[empty output, obviating "broken pipe" error]


And I'm not sure that fully does it still because there is this:

  pos = file.find_last_of (file_ops::dir_sep_chars ());

which I think is meant to find a device file (??). What if a file name is given but there is no directory character? Or does there have to be a directory character by nature of the OS file system?

Dan



reply via email to

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