Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Question related to string functions

Reply
Thread Tools

Question related to string functions

 
 
somenath
Guest
Posts: n/a
 
      09-10-2007
Hi All,

I was going through one piece of code which is written by an
experience programmer and it is working fine.
But I think the use of "strstr" is not proper because it may show
undefined behavior.



char *returnValueFromIniFile(char *iniFilePath,char *keyIntheFile)
{
FILE *FD_IniFileP =NULL;
char key[SIZE_OF_ARRAY]={'0'};
static char value[SIZE_OF_ARRAY]={'\0'};
FD_IniFileP = fopen(iniFilePath,"r");
if( FD_IniFileP != NULL )
{
/* File Open Success*/
while (fscanf(FD_IniFileP,"%s",key)!= EOF)
{
if(strstr(key,keyIntheFile)!=NULL)
{


/*Make sure key contains "="*/
if(strstr(key,"=")!=NULL)
{
/*Sepereate the key and the value */
char *positionOfequal = strstr(key,"="); /* as "="
is not terminated by '\0' it can show undefined behavior ? */

/*increment the positionOfequal to reach the
beganing of the value */
positionOfequal +=1;
assert(strlen(positionOfequal)<SIZE_OF_ARRAY);
strcpy(value,positionOfequal);
break;
}

}/* End of if(strstr(key,keyIntheFile)!=NULL)*/
memset(key,'\0',SIZE_OF_ARRAY);

}/* End of while (fscanf(FD_IniFileP,"%s",key)!= EOF)*/

}/* End of if( FD_IniFileP != NULL )*/
if (FD_IniFileP)
{
fclose(FD_IniFileP);
}

return value;

}

I think the statement "char *positionOfequal = strstr(key,"=");" can
show undefined behavior .
1) Is my understanding correct ?
I have another question
2) Can we pass directly sequence of characters to the function which
expects string ?
For example strcpy(dest,"some");
Strcat(dest,"abc"); ?
Regards,
Somenath

 
Reply With Quote
 
 
 
 
Richard Heathfield
Guest
Posts: n/a
 
      09-10-2007
somenath said:

> Hi All,
>
> I was going through one piece of code which is written by an
> experience programmer and it is working fine.


It fails to protect its key buffer against overruns, so I can't agree
that it's working fine.

> But I think the use of "strstr" is not proper because it may show
> undefined behavior.


<snip>

> if(strstr(key,keyIntheFile)!=NULL)
> {
>
>
> /*Make sure key contains "="*/
> if(strstr(key,"=")!=NULL)
> {
> /*Sepereate the key and the value */
> char *positionOfequal = strstr(key,"=");


Calling strstr twice here seems to be a little unnecessary. Still, it's
not actually wrong. Incidentally, strchr would have been adequate.

/* as "="
> is not terminated by '\0' it can show undefined behavior ? */


"=" is a string literal, which *IS* terminated by a null character.

<snip>

> 2) Can we pass directly sequence of characters to the function which
> expects string ?
> For example strcpy(dest,"some");
> Strcat(dest,"abc"); ?


Yes, you can pass string literals to standard library functions when you
are matching parameters that take const char * (as in your strcpy
example). I can't answer for your Strcat example, since I've never
heard of a Strcat function. If you meant strcat, then yes, that, too,
can legitimately take a string literal as the second argument.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
 
 
 
somenath
Guest
Posts: n/a
 
      09-10-2007
On Sep 10, 8:33 am, Richard Heathfield <(E-Mail Removed)> wrote:
> somenath said:
>
> > Hi All,

>
> > I was going through one piece of code which is written by an
> > experience programmer and it is working fine.

>
> It fails to protect its key buffer against overruns, so I can't agree
> that it's working fine.


Many thanks for the response.

If i have propely understood you are indicating that " while
(fscanf(FD_IniFileP,"%s",key)!= EOF) "
can cause problem . is it so ?
if it is then if I change the code as following will it solve the
problem ?
#define str(x) # x
#define xstr(x) str(x)


char *returnValueFromIniFile(char *iniFilePath,char *keyIntheFile)
{
FILE *FD_IniFileP =NULL;
char key[SIZE_OF_ARRAY+1]={'0'};
static char value[1]={'\0'};
FD_IniFileP = fopen(iniFilePath,"r");
if( FD_IniFileP != NULL )
{
/* File Open Success*/
//cout<<"\n Opening of INI file Succeeded \n "<<endl;
while (fscanf(FD_IniFileP,"%" xstr(SIZE_OF_ARRAY) "[^
\n]" ,key)!= EOF)
{



>
> > But I think the use of "strstr" is not proper because it may show
> > undefined behavior.

>
> <snip>
>
> > if(strstr(key,keyIntheFile)!=NULL)
> > {

>
> > /*Make sure key contains "="*/
> > if(strstr(key,"=")!=NULL)
> > {
> > /*Sepereate the key and the value */
> > char *positionOfequal = strstr(key,"=");

>
> Calling strstr twice here seems to be a little unnecessary. Still, it's
> not actually wrong. Incidentally, strchr would have been adequate.
>
> /* as "="
>
> > is not terminated by '\0' it can show undefined behavior ? */

>
> "=" is a string literal, which *IS* terminated by a null character.
>
> <snip>
>
> > 2) Can we pass directly sequence of characters to the function which
> > expects string ?
> > For example strcpy(dest,"some");
> > Strcat(dest,"abc"); ?

>
> Yes, you can pass string literals to standard library functions when you
> are matching parameters that take const char * (as in your strcpy
> example). I can't answer for your Strcat example, since I've never
> heard of a Strcat function. If you meant strcat,


Sorry it is my typing mistake. It would be strcat.

> then yes, that, too,
> can legitimately take a string literal as the second argument.




 
Reply With Quote
 
somenath
Guest
Posts: n/a
 
      09-10-2007
On Sep 10, 8:33 am, Richard Heathfield <(E-Mail Removed)> wrote:
> somenath said:
>
> > Hi All,

>
> > I was going through one piece of code which is written by an
> > experience programmer and it is working fine.

>
> It fails to protect its key buffer against overruns, so I can't agree
> that it's working fine.
>
> > But I think the use of "strstr" is not proper because it may show
> > undefined behavior.

>
> <snip>
>
> > if(strstr(key,keyIntheFile)!=NULL)
> > {

>
> > /*Make sure key contains "="*/
> > if(strstr(key,"=")!=NULL)
> > {
> > /*Sepereate the key and the value */
> > char *positionOfequal = strstr(key,"=");

>
> Calling strstr twice here seems to be a little unnecessary. Still, it's
> not actually wrong. Incidentally, strchr would have been adequate.
>
> /* as "="
>
> > is not terminated by '\0' it can show undefined behavior ? */

>
> "=" is a string literal, which *IS* terminated by a null character.
>
> <snip>
>
> > 2) Can we pass directly sequence of characters to the function which
> > expects string ?
> > For example strcpy(dest,"some");
> > Strcat(dest,"abc"); ?

>
> Yes, you can pass string literals to standard library functions when you
> are matching parameters that take const char * (as in your strcpy
> example). I can't answer for your Strcat example, since I've never
> heard of a Strcat function. If you meant strcat, then yes, that, too,
> can legitimately take a string literal as the second argument.
>

I have one doubt here.
Suppose
#define TEMP_STR "xyz"
can i use string related function such as strcpy(dest,TEMP_STR); ?

 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      09-10-2007
somenath said:

> On Sep 10, 8:33 am, Richard Heathfield <(E-Mail Removed)> wrote:


<snip>

>> Yes, you can pass string literals to standard library functions when
>> you are matching parameters that take const char * (as in your strcpy
>> example). [...]
>>

> I have one doubt here.
> Suppose
> #define TEMP_STR "xyz"
> can i use string related function such as strcpy(dest,TEMP_STR); ?


Yes, because it's just a different way of writing strcpy(dest,"xyz");

But TEMP_STR is a bad name for a string literal. String literals exist
for the entire lifetime of the program, so they are hardly temporary!

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      09-10-2007
somenath <(E-Mail Removed)> writes:
> I was going through one piece of code which is written by an
> experience programmer and it is working fine.
> But I think the use of "strstr" is not proper because it may show
> undefined behavior.

[...]
> /*Sepereate the key and the value */
> char *positionOfequal = strstr(key,"="); /* as "="
> is not terminated by '\0' it can show undefined behavior ? */

[...]
> I think the statement "char *positionOfequal = strstr(key,"=");" can
> show undefined behavior .
> 1) Is my understanding correct ?
> I have another question
> 2) Can we pass directly sequence of characters to the function which
> expects string ?
> For example strcpy(dest,"some");
> Strcat(dest,"abc"); ?


A string literal is (almost) always implicitly terminated by a '\0'
character. The literal "=" specifies the two-character sequence
'=', '\0'.

(The only exception is when a string literal is used to initialize an
array whose size is specified as exactly the length of the array, such
as
char s[3] = "abc";
but this is a very unusual case, and should be avoided; instead, you
can use
char s[] = "abc";
to get a properly zero-terminated string.)

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Richard Heathfield
Guest
Posts: n/a
 
      09-10-2007
Keith Thompson said:

> somenath <(E-Mail Removed)> writes:
>> I was going through one piece of code which is written by an
>> experience programmer and it is working fine.
>> But I think the use of "strstr" is not proper because it may show
>> undefined behavior.

> [...]
>> /*Sepereate the key and the value */
>> char *positionOfequal = strstr(key,"="); /* as
>> "="
>> is not terminated by '\0' it can show undefined behavior ? */

> [...]
>> I think the statement "char *positionOfequal = strstr(key,"=");" can
>> show undefined behavior .
>> 1) Is my understanding correct ?
>> I have another question
>> 2) Can we pass directly sequence of characters to the function which
>> expects string ?
>> For example strcpy(dest,"some");
>> Strcat(dest,"abc"); ?

>
> A string literal is (almost) always implicitly terminated by a '\0'
> character. The literal "=" specifies the two-character sequence
> '=', '\0'.
>
> (The only exception is when a string literal is used to initialize an
> array whose size is specified as exactly the length of the array, such
> as
> char s[3] = "abc";


What makes you think this is an exception?

The Standard says:

"A character string literal has static storage duration and type "array
of char," and is initialized with the given characters. A wide string
literal has static storage duration and type "array of wchar_t," and is
initialized with the wide characters corresponding to the given
multibyte characters. Character string literals that are adjacent
tokens are concatenated into a single character string literal. A null
character is then appended."

No exceptions.

I know what you're thinking of, but that's a special case of
initialisation, not a special case of string literals.


> but this is a very unusual case, and should be avoided;


....by newbies, at any rate. There are (rare) times when it's Exactly
What's Needed.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      09-10-2007
Richard Heathfield <(E-Mail Removed)> writes:
> Keith Thompson said:

[...]
>> A string literal is (almost) always implicitly terminated by a '\0'
>> character. The literal "=" specifies the two-character sequence
>> '=', '\0'.
>>
>> (The only exception is when a string literal is used to initialize an
>> array whose size is specified as exactly the length of the array, such
>> as
>> char s[3] = "abc";

>
> What makes you think this is an exception?
>
> The Standard says:
>
> "A character string literal has static storage duration and type "array
> of char," and is initialized with the given characters. A wide string
> literal has static storage duration and type "array of wchar_t," and is
> initialized with the wide characters corresponding to the given
> multibyte characters. Character string literals that are adjacent
> tokens are concatenated into a single character string literal. A null
> character is then appended."
>
> No exceptions.
>
> I know what you're thinking of, but that's a special case of
> initialisation, not a special case of string literals.


What are you, some kind of pedant?

}

Yeah, you're right. C99 6.7.8p14 says:

An array of character type may be initialized by a character
string literal, optionally enclosed in braces. Successive
characters of the character string literal (including the
terminating null character if there is room or if the array is of
unknown size) initialize the elements of the array.

>> but this is a very unusual case, and should be avoided;

>
> ...by newbies, at any rate. There are (rare) times when it's Exactly
> What's Needed.


Hmm. I meant to qualify that somehow, and I thought I had.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Bart van Ingen Schenau
Guest
Posts: n/a
 
      09-10-2007
somenath wrote:

> On Sep 10, 8:33 am, Richard Heathfield <(E-Mail Removed)> wrote:
>> somenath said:
>>
>> > Hi All,

>>
>> > I was going through one piece of code which is written by an
>> > experience programmer and it is working fine.

>>
>> It fails to protect its key buffer against overruns, so I can't agree
>> that it's working fine.

>
> Many thanks for the response.
>
> If i have propely understood you are indicating that " while
> (fscanf(FD_IniFileP,"%s",key)!= EOF) "
> can cause problem . is it so ?
> if it is then if I change the code as following will it solve the
> problem ?
> #define str(x) # x
> #define xstr(x) str(x)
>
>
> char *returnValueFromIniFile(char *iniFilePath,char *keyIntheFile)
> {
> FILE *FD_IniFileP =NULL;
> char key[SIZE_OF_ARRAY+1]={'0'};
> static char value[1]={'\0'};
> FD_IniFileP = fopen(iniFilePath,"r");
> if( FD_IniFileP != NULL )
> {
> /* File Open Success*/
> //cout<<"\n Opening of INI file Succeeded \n "<<endl;
> while (fscanf(FD_IniFileP,"%" xstr(SIZE_OF_ARRAY) "[^
> \n]" ,key)!= EOF)
> {
>


Yes, that will properly protect you from a buffer overrun of the key
array.
But your change also changes the semantics of the program.
The original line:
*while (fscanf(FD_IniFileP,"%s",key)!= EOF)
would stop reading on the first whitespace character, but your rewrite
only stops at the end of a line.
To preserve the original semantics, you should use
while (fscanf(FD_IniFileP,"%" xstr(SIZE_OF_ARRAY) "s" ,key)!= EOF)

Bart v Ingen Schenau
--
a.c.l.l.c-c++ FAQ: http://www.comeaucomputing.com/learn/faq
c.l.c FAQ: http://www.eskimo.com/~scs/C-faq/top.html
c.l.c++ FAQ: http://www.parashift.com/c++-faq-lite/
 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      09-10-2007

"Keith Thompson" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Richard Heathfield <(E-Mail Removed)> writes:
>> I know what you're thinking of, but that's a special case of
>> initialisation, [ unterminated char arrays] not a special case of
>> string literals.

>
> What are you, some kind of pedant?
>

If we can't be literal about literals, where is it appropriate?

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

 
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
WebForm_PostBackOptions and related functions Jeremy Chapman ASP .Net 0 06-26-2006 04:52 AM
How should multiple (related) projects be arranged (structured) and configured so that they can share code, have a related package structure and enable proper unittesting, and ensuring no namespace collisions ToddLMorgan@gmail.com Python 14 04-21-2006 04:03 PM
How should threads be terminated? (related to 'Help with thread related tracebacks') Maxwell Hammer Python 7 06-18-2005 04:20 PM
please help me in distinguish redefining functions, overloading functions and overriding functions. Xiangliang Meng C++ 1 06-21-2004 03:11 AM
Memory related functions.... james C++ 2 02-20-2004 05:35 PM



Advertisments