|
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
[Prev in Thread] | Current Thread | [Next in Thread] |