Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > sscanf up to 127 characters into a buffer?

Reply
Thread Tools

sscanf up to 127 characters into a buffer?

 
 
mathog
Guest
Posts: n/a
 
      03-14-2013
Is this sscanf adequate to prevent a buffer overflow if
the input text field is >127 characters in length? The goal
is to put everything from the first character of the text
following the 3 floats to the end of the line into fontname.
But only if it will all fit into the buffer.

int elements;
float f1,f2,f3;
char fontname[128];
char *string;
while(1){
/* load the string from a file, or exit loop on EOF
Input lines look like:
1.23 2.34 -1.2323 some text here
*/
elements = sscanf(string,
"%lf %lf %lf %127[^\n]",
&f1,&f2,&f3, &fontname[0]);
/* do something with the values */
}

The code at present lacks the 127, and I assume
that it would generate a memory access error on an excessively long
input line.

Thanks,

David Mathog
 
Reply With Quote
 
 
 
 
Joe Pfeiffer
Guest
Posts: n/a
 
      03-14-2013
mathog <(E-Mail Removed)> writes:

> Is this sscanf adequate to prevent a buffer overflow if
> the input text field is >127 characters in length? The goal
> is to put everything from the first character of the text
> following the 3 floats to the end of the line into fontname.
> But only if it will all fit into the buffer.
>
> int elements;
> float f1,f2,f3;
> char fontname[128];
> char *string;
> while(1){
> /* load the string from a file, or exit loop on EOF
> Input lines look like:
> 1.23 2.34 -1.2323 some text here
> */
> elements = sscanf(string,
> "%lf %lf %lf %127[^\n]",
> &f1,&f2,&f3, &fontname[0]);
> /* do something with the values */
> }
>
> The code at present lacks the 127, and I assume
> that it would generate a memory access error on an excessively long
> input line.


Almost...

%lf looks for a double, not a float. You need to either declare
double f1, f2, f3;
or use %f

sscanf() doesn't know about regular expressions. %127[^\n] is
meaningless. %127s would read a string of up to 127 characters, but it
couldn't contain any white space.

If I were doing this, I'd probably use three calls to strtok() to pull
off the floats (and then use atof to convert them), and strncpy() to
pull the name into the buffer (note that you have to make sure that if
the font is too long to fit in the buffer you get properly
null-terminated yourself).
 
Reply With Quote
 
 
 
 
mathog
Guest
Posts: n/a
 
      03-14-2013
Joe Pfeiffer wrote:
> Almost...
>
> %lf looks for a double, not a float. You need to either declare
> double f1, f2, f3;


Sorry brain fart typing in the small example, the original, much larger,
code uses double.

> or use %f
>
> sscanf() doesn't know about regular expressions. %127[^\n] is
> meaningless.


Hmm, not meaningless, but perhaps a gcc extension?
The man page for scanf says:

[ Matches a nonempty sequence of characters from the
specified set of accepted characters; the next pointer must be a pointer
to char, and there must be enough room for all the characters in the
string, plus a terminating null byte. ...

Regards,

David Mathog
 
Reply With Quote
 
mathog
Guest
Posts: n/a
 
      03-14-2013
Joe Pfeiffer wrote:

> sscanf() doesn't know about regular expressions. %127[^\n] is
> meaningless.


After some searching, it is not a gcc extension, but part of C99,
section 7.19.6.2. Information from here:

http://stackoverflow.com/questions/5...ort-a-standard

> %127s would read a string of up to 127 characters, but it
> couldn't contain any white space.


%127[^\n] does move white space characters into the buffer.

Regards,

David Mathog




 
Reply With Quote
 
Joe Pfeiffer
Guest
Posts: n/a
 
      03-14-2013
mathog <(E-Mail Removed)> writes:

> Joe Pfeiffer wrote:
>>
>> sscanf() doesn't know about regular expressions. %127[^\n] is
>> meaningless.

>
> Hmm, not meaningless, but perhaps a gcc extension?
> The man page for scanf says:
>
> [ Matches a nonempty sequence of characters from the
> specified set of accepted characters; the next pointer must be a
> pointer to char, and there must be enough room for all the characters
> in the string, plus a terminating null byte. ...


I apologize! checking, it's even in the C99 standard. I don't know
when it was added.
 
Reply With Quote
 
Joe Pfeiffer
Guest
Posts: n/a
 
      03-14-2013
mathog <(E-Mail Removed)> writes:

> Joe Pfeiffer wrote:
>
>> sscanf() doesn't know about regular expressions. %127[^\n] is
>> meaningless.

>
> After some searching, it is not a gcc extension, but part of C99,
> section 7.19.6.2. Information from here:
>
> http://stackoverflow.com/questions/5...ort-a-standard
>
>> %127s would read a string of up to 127 characters, but it
>> couldn't contain any white space.

>
> %127[^\n] does move white space characters into the buffer.


I stand corrected.
 
Reply With Quote
 
Lew Pitcher
Guest
Posts: n/a
 
      03-14-2013
On Thursday 14 March 2013 15:56, in comp.lang.c, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:

> Joe Pfeiffer wrote:
>> Almost...
>>
>> %lf looks for a double, not a float. You need to either declare
>> double f1, f2, f3;

>
> Sorry brain fart typing in the small example, the original, much larger,
> code uses double.
>
>> or use %f
>>
>> sscanf() doesn't know about regular expressions. %127[^\n] is
>> meaningless.

>
> Hmm, not meaningless, but perhaps a gcc extension?


Nope. It's there in the C 1999 standard

ISO/IEC C 9899-1999 7.19.6.2 ("The fscanf function") paragraph 12 states:

12 The conversion specifiers and their meanings are:
...
[ Matches a nonempty sequence of characters from a set of expected
characters (the scanset)) If no l length modifier is present, the
corresponding argument shall be a pointer to the initial element of a
character array large enough to accept the sequence and a terminating
null character, which will be added automatically.

If an l length modifier is present, the input shall be a sequence of
multibyte characters that begins in the initial shift state. Each
multibyte character is converted to a wide character as if by a call to
the mbrtowc function, with the conversion state described by an
mbstate_t object initialized to zero before the first multibyte
character is converted. The corresponding argument shall be a pointer
to the initial element of an array of wchar_t large enough to accept
the sequence and the terminating null wide character, which will be
added automatically.

The conversion specifier includes all subsequent charactersin the
format string, up to and including the matching right bracket (]).The
characters between the brackets (the scanlist) compose the scanset,
unless the character after the left bracket is a circumflex(ˆ), in
which case the scanset contains all characters that do not appear in
the scanlist between the circumflex and the right bracket. If the
conversion specifier begins with [] or [ˆ], the right bracket character
is in the scanlist and the next following right bracket character is
the matching right bracket that ends the specification; otherwise the
first following right bracket character is the one that ends the
specification. If a - character is in the scanlist and is not the first,
nor the second where the first character is a ˆ, nor the last character,
the behavior is implementation-defined.


--
Lew Pitcher
"In Skills, We Trust"
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      03-14-2013
Joe Pfeiffer <(E-Mail Removed)> writes:
> mathog <(E-Mail Removed)> writes:
>> Is this sscanf adequate to prevent a buffer overflow if
>> the input text field is >127 characters in length? The goal
>> is to put everything from the first character of the text
>> following the 3 floats to the end of the line into fontname.
>> But only if it will all fit into the buffer.
>>
>> int elements;
>> float f1,f2,f3;
>> char fontname[128];
>> char *string;
>> while(1){
>> /* load the string from a file, or exit loop on EOF
>> Input lines look like:
>> 1.23 2.34 -1.2323 some text here
>> */
>> elements = sscanf(string,
>> "%lf %lf %lf %127[^\n]",
>> &f1,&f2,&f3, &fontname[0]);
>> /* do something with the values */
>> }
>>
>> The code at present lacks the 127, and I assume
>> that it would generate a memory access error on an excessively long
>> input line.

>
> Almost...
>
> %lf looks for a double, not a float. You need to either declare
> double f1, f2, f3;
> or use %f
>

[...]
>
> If I were doing this, I'd probably use three calls to strtok() to pull
> off the floats (and then use atof to convert them), and strncpy() to
> pull the name into the buffer (note that you have to make sure that if
> the font is too long to fit in the buffer you get properly
> null-terminated yourself).


atof() doesn't detect errors; strtod() does.

strncpy() is rarely the right answer. It usually either fails to
null-terminate the target array, or pads it to the end with unnecessary
null characters. I ranted about it here:

http://the-flat-trantor-society.blog...er-strcpy.html

If you can confirm that there's enough room in the target, just use
strcpy(). If there isn't enough room, you'll have to decide how to
handle that; strncpy()'s behavior in that case is probably not what you
want.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      03-14-2013
On 3/14/2013 4:13 PM, Joe Pfeiffer wrote:
> mathog <(E-Mail Removed)> writes:
>
>> Joe Pfeiffer wrote:
>>>
>>> sscanf() doesn't know about regular expressions. %127[^\n] is
>>> meaningless.

>>
>> Hmm, not meaningless, but perhaps a gcc extension?
>> The man page for scanf says:
>>
>> [ Matches a nonempty sequence of characters from the
>> specified set of accepted characters; the next pointer must be a
>> pointer to char, and there must be enough room for all the characters
>> in the string, plus a terminating null byte. ...

>
> I apologize! checking, it's even in the C99 standard. I don't know
> when it was added.


It was added in 1989 by ANSI, but not until 1990 by ISO.

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      03-14-2013
On 3/14/2013 4:04 PM, mathog wrote:
> Joe Pfeiffer wrote:
>
>> sscanf() doesn't know about regular expressions. %127[^\n] is
>> meaningless.

>
> After some searching, it is not a gcc extension, but part of C99,
> section 7.19.6.2. Information from here:
>
> http://stackoverflow.com/questions/5...ort-a-standard
>
>
>> %127s would read a string of up to 127 characters, but it
>> couldn't contain any white space.

>
> %127[^\n] does move white space characters into the buffer.


Yes. With your format string, though:

elements = sscanf(string,
"%lf %lf %lf %127[^\n]",
&f1,&f2,&f3, &fontname[0]);

.... the "%[" directive will move no leading white space, because
it's already been eaten by the " " immediately before. (It will,
however, move embedded and trailing white space, up to but not
including the '\n'.) If you want the leading spaces, try

elements = sscanf(string,
"%lf%lf%lf%127[^\n]",
&f1,&f2,&f3, &fontname[0]);

--
Eric Sosman
(E-Mail Removed)d
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
sscanf'ing floats into structure members Bernard Liang C Programming 3 06-21-2006 09:06 PM
[FR/EN] how to convert the characters ASCII(0-255) to ASCII(0-127) Alextophi Perl Misc 8 12-30-2005 10:43 AM
Re: Is it safe to put 127.0.0.1 into ZA's trusted zone? Sandi Computer Security 1 03-06-2005 05:40 AM
isdigit() for characters greater than 127 Alf P. Steinbach C++ 4 10-09-2004 06:37 AM
filter special characters ( ascii > 127) in Change password kike Javascript 0 07-20-2004 01:13 AM



Advertisments