Ethereal-dev: RE: [Ethereal-dev] LDAP/SIP truncation problems ... snprintf and vsnprintf non

Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.

From: "HOOD, Andy" <ahood@xxxxxxxxxxxxxx>
Date: Thu, 19 Dec 2002 08:50:58 +1100
My normal response to snprintf (and friends) behaviour is to put something
like "buf[sizeof(buf)]=0;" immediately after the call, so I'm sure the
string is null terminated, and works irrespective of standards compliance -
or lack thereof.

Regards,
Andrew Hood
A distributed system is one in which the failure of a computer you
didn't even know existed can render your own computer unusable. --
Leslie Lamport, as quoted in CACM, June 1992




> -----Original Message-----
> From: Ronald Henderson [mailto:Ronald.Henderson@xxxxxxxxxxxxxxxx]
> Sent: Thursday, 19 December 2002 05:38
> To: 'ethereal-dev@xxxxxxxxxxxx'
> Subject: [Ethereal-dev] LDAP/SIP truncation problems ... snprintf and
> vsnprintf non-term ination causes blank lines in proto trees values on
> windows platform...
> 
> 
> Folks:
> 
> Marting Regner and I need your desired coding fix based on 
> discovering the
> cause of blank lines or garbage data at the end of the value 
> that appears on
> the windows platform for LDAP and SIP protocols when values exceed the
> ITEM_LABEL_LENGTH limit. This behavior is different for the 
> Linux platform.
> The C runtime libraries do not insert a termination character 
> '\0' for the
> snprintf() and vsnprintf()  functions if the value exceeds 
> the size limit.
> These functions are found in the "proto.c" file. Currently 
> the returned
> value is not used for these functions in "proto.c"
> 
> Windows:
> =======
> 
> For the windows platform, if a value exceeds the size limit 
> (in our case
> ITEM_LABEL_LENGTH) the associated character buffer used in 
> the snprintf() or
> vsnprinf() function will not be null terminated. This causes 
> no data to be
> displayed or extra printable characters to be displayed at 
> the end of the
> value.
> 
> Reason for blank line: On the windows platform if a value to 
> be displayed
> contains a non-printable character (i.e. octet value greater 
> than 0x7F) no
> data will be displayed at all for that value. Since the snprintf() or
> vnsprintf() don't terminate the char buffer if the value is 
> greater than:
> ITEM_LABEL_LENGTH printing for that value will continue until a null
> terminating character is found. If a non-printing character 
> exists from the
> beginning of the of the char buffer to the false null 
> terminating character
> no data is printed. A simple modification to force printing 
> under windows
> for FT_STRING types is to change code in the function  
> format_text(const
> guchar *string, int len) file strutil.c
> 
> From:
> if (isprint(c)) {
> 
> To:
> if (isprint(c) && (c < 128)) {
> 
> This forces octal character printing (i.e. \nnn) for 
> non-printal characters
> and the data for that value is now displayed...
> 
> Reason for extra characters at end of value: Once again printing will
> continue until a null character is found. If all characters 
> are printable
> extra garbage printable characters will be found at the end 
> of the value...
> 
> Here is microsoft's definition of the snprintf() function... 
> 
> Microsoft snprintf() (MSVC 6.0) docs:
> ===========================
> ...
> _vsnprintf and _vsnwprintf return the number of characters 
> written, not
> including the terminating null character, or a negative value 
> if an output
> error occurs. For _vsnprintf, if the number of bytes to write exceeds
> buffer, then count bytes are written and -1 is returned.
> ...
> 
> 
> 
> Linux:
> ======
> For the linux platform the behavior for the snprintf() and 
> vsnprintf() are
> the similar as far as the null terminating character is 
> concern (i.e. there
> will be none if the value exceeds the size limit). But what 
> is different is
> the non-printable character are shown as garbage characters, 
> therefore no
> blank lines. Extra characters will also show up until a null 
> termination
> character is found.
> 
> Linux: Man Page for snprintf()
> ==============================
> ...
>  Return value
>        Upon successful return, these functions return the number of
> characters printed  (not  including  the  trailing  '\0'  
> used  to  end
> output to strings).  The functions snprintf and vsnprintf do 
> not write more
> than       size  bytes (including the trailing '\0').  If the 
> output was
> truncated due to this limit then the return value is  the  number  of
> characters (not  including the trailing '\0') which would 
> have been written
> to the final string if enough space had been available. Thus, 
> a  return
> value of  size  or  more means that the output was truncated. 
> (See also
> below under NOTES.)  If an output error is encountered, a 
> negative  value
> is returned.
> ...  
> NOTES
>        The  glibc  implementation of the functions snprintf 
> and vsnprintf
> conforms to the C99 standard, i.e.,  behaves  as  described  
> above,  since
> glibc version 2.1. Until glibc 2.0.6 they would return -1 
> when the output
> was truncated.
> ...
> 
> 
> Questions:
> =========
> How would you like the fix to be in proto.c?
> 
> 1) Does this check have to be corrected for every instance of 
> snprintf() and
> vsnprintf() or just for proto values that make since (i.e. FT_STRING)?
> 
> 2) From what I see the check needs to be for return values of 
> -1 or size
> greater than or equal to ITEM_LABEL_LENGTH
> 
> 3) Should a compiler directive be used here for a Windows 
> build vs a Unix
> build (i.e. #ifdef _WIN32)?
> 
> 
> Looking forward to your responses....
> 
> 
> ---Ronald W. Henderson
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
>   
> _______________________________________________
> Ethereal-dev mailing list
> Ethereal-dev@xxxxxxxxxxxx
> http://www.ethereal.com/mailman/listinfo/ethereal-dev
> 

<<application/ms-tnef>>