slang-users mailing list

[2005 Date Index] [2005 Thread Index] [Other years]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]

[slang-users] Promoting SLvsnprintf and SLsnprintf to officially exported funct ions


Hi,
 
As people reading the Jed mailing list knows, I'm trying to fix some
glitches of Windows Jed. Sometimes this means changing something on Slang, I
will try to put here things that are Slang-related.

I want to declare two "private" slang functions (_pSLsnprintf and
_pSLvsnprintf) public. Please note that:
- Are already used externally (at least by Jed).
- Are useful as wrappers to hide system differences: the return code changes
from system to system, ans some old systems doesn't have an implementation
at all.

The current implementation has some problems: Slang expects that system
version, if exists, return EOF, but this is not tested by configure, so for
example or recent linuxes (with glibc >= 2.1) this is not true, as from that
version they follow the C99 standard, so the return value is the size needed
for a correct output (the old glibc versions, and also Visual Studio 6,
returns -1).
Quoting man snprintf:

------- quote begin
   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 writ-
       ten 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 neg-
       ative value is returned.

[SNIP]

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.

[SNIP]

       Concerning  the  return  value  of snprintf, the SUSv2 and the C99
standard contradict each other: when
       snprintf is called with size=0 then SUSv2 stipulates an unspecified
return value less than 1, while C99
       allows  str to be NULL in this case, and gives the return value (as
always) as the number of characters
       that would have been written in case the output string has been large
enough.
-------- quote end

MSDN October 2004 says:

-------- quote begin
Return Value
_snprintf returns the number of bytes stored in buffer, not counting the
terminating null character. If the number of bytes required to store the
data exceeds count, then count bytes of data are stored in buffer and a
negative value is returned. 

Security Note   Ensure that format is not a user-defined string. This
function does not guarantee NULL termination, so ensure it is followed by
sz[ ARRAYSIZE(sz) - 1] = 0.
-------- quote end

Note that while for most systems EOF == -1, this is not mandatory.

So I propose to:
- rename the functions to SLvsnprintf and SLsnprintf.
- declare both on slang.h
- define SLvsnprintf as returning -1 on error, and handle internally systems
returning size.
- keep the poors man implementation for systems without vsnprintf.
- implement SLsnprintf using SLvsnprintf.

I still things that the C99 standard is the correct way to do this, but if
the system snprintf returns -1 externally we can only guess the real buffer
size, so implementing SLsnprintf as returning the required buffer size is
difficult, complex and time-consuming.

The attached patch against SLang-pre2-r5 does:
- Removes definitions from _slang.h
- Adds new ones to slang.h
- reimplement functions.
- Changes all the callers within slang the the new names.
- changes all the return value tests against EOF to -1.
- #define HAVE_SNPRINTF and HAVE_VSNPRINT in slconfig.h if _MSC_VER is
defined (at least Visual Studio 6 has these).

I don't know if some system has a working snprintf implementation but not a
vsnprintf. If suvh a beast exists, on those system we loose the snprintf
protection. I we care about this we can add to slang.h something like:
#if defined(HAVE_SNPRINTF) && !defined(HAVE_VSNPRINTF)
/* avoid using the unsafe SLvsnprintf to implement SLsnprintf as we have a
working snprintf */
#define SLsnprintf snprintf
#else
extern int SLvsnprintf (char *buf, unsigned int buflen, char *fmt, va_list
ap);
#endif

And exclude compilation definition.
But this way we can only hope that the system snprintf return -1 on buffer
not big enough.

Comments?

Later,
							Dino


Attachment: slang-export-SLsnprintf.diff
Description: Binary data

_______________________________________________
To unsubscribe, visit http://jedsoft.org/slang/mailinglists.html

[2005 date index] [2005 thread index]
[Thread Prev] [Thread Next]      [Date Prev] [Date Next]