Bug 1865 - extend snprintf to work on NULL
Summary: extend snprintf to work on NULL
Status: RESOLVED FIXED
Alias: None
Product: xorg
Classification: Unclassified
Component: Lib/other (show other bugs)
Version: git
Hardware: x86 (IA32) All
: high normal
Assignee: Xorg Project Team
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 1802 2245
  Show dependency treegraph
 
Reported: 2004-11-15 06:41 UTC by Alexander Gottwald
Modified: 2005-02-02 07:50 UTC (History)
0 users

See Also:
i915 platform:
i915 features:


Attachments
allow snprintf to work on NULL buffer (921 bytes, patch)
2004-11-15 06:42 UTC, Alexander Gottwald
no flags Details | Splinter Review
add Xprintf and XNFprintf to xserver (3.13 KB, patch)
2004-11-25 06:02 UTC, Alexander Gottwald
no flags Details | Splinter Review
check for va_copy not being defined and use __va_copy if available (539 bytes, patch)
2005-02-03 01:55 UTC, Alexander Gottwald
no flags Details | Splinter Review

Description Alexander Gottwald 2004-11-15 06:41:45 UTC
A lot of platforms have snprintf code which works even if the supplied buffer is
NULL. eg snprintf(NULL, 0, format, ...) will give the size of the formatted string.

The patch adds a few checks for str == NULL to prevent segfaults.
Comment 1 Alexander Gottwald 2004-11-15 06:42:26 UTC
Created attachment 1311 [details] [review]
allow snprintf to work on NULL buffer
Comment 2 Kristian Høgsberg 2004-11-23 18:58:58 UTC
Yay, go for it.  I have the same change in one of my local trees.  It quite
useful, we should implement a xallocPrintf(const char *fmt, ...) which allocs
the required space and snprintf()'s into it.
Comment 3 Alexander Gottwald 2004-11-24 02:27:34 UTC
glibc has an asprintf(char **str, const char *format, ...) for this

I'm about to use this implementation for XWin

#ifndef HAS_VASPRINTF
extern int vasprintf(char **strp, const char *format, va_list va)
{
    int ret;
    int size;
    va_list va2;

    va_copy(va2, va);
    size = vsnprintf(NULL, 0, format, va2);
    va_end(va2);

    *strp = malloc(size + 1);
    if (*strp == NULL)
        return -1;

    ret = vsnprintf(*strp, size + 1, format, va);
    (*strp)[size] = 0;
    return ret;
}
#endif

#ifndef HAS_ASPRINTF
extern int asprintf(char **strp, const char *format, ...)
{
    int ret;
    va_list va;
    va_start(va, format);
    ret = vasprintf(strp, format, va);
    va_end(va);
    return ret;
}
#endif
Comment 4 Kristian Høgsberg 2004-11-24 10:44:26 UTC
Yeah, that looks good.  My only concern is that you're using malloc(), shouldn't
that be xalloc()?  Of course, in that case it wouldn't be asprintf() (which is
documented as using malloc()), which is why I originally suggested
xallocPrintf() ... for symmetry, I think a "no fail" xnfallocPrintf() would be
cool, too.
Comment 5 Alexander Gottwald 2004-11-25 06:02:18 UTC
Created attachment 1370 [details] [review]
add Xprintf and XNFprintf to xserver

Xprintf and Xvprintf allocate the buffer via Xalloc
XNFprintf and XNFvprintf allocate it via XNFalloc

should the macros x*printf be added? And how

a simple 
#define xprintf Xprintf
or more complicated like
#define xvprintf(fmt, ...) Xvprintf(fmt, ???)
is this portable? I think macros with variable arguments is a gnu extension
Comment 6 Alexander Gottwald 2004-12-03 03:59:50 UTC
/cvs/xorg/xc/ChangeLog,v  <--  ChangeLog
new revision: 1.563; previous revision: 1.562
/cvs/xorg/xc/programs/Xserver/include/os.h,v  <--  os.h
new revision: 1.5; previous revision: 1.4
/cvs/xorg/xc/programs/Xserver/os/xprintf.c,v  <--  xprintf.c
initial revision: 1.1
/cvs/xorg/xc/programs/Xserver/os/Imakefile,v  <--  Imakefile
new revision: 1.7; previous revision: 1.6
/cvs/xorg/xc/lib/misc/snprintf.c,v  <--  snprintf.c
new revision: 1.3; previous revision: 1.2

marked as fixed...
Comment 7 Alexander Gottwald 2005-02-03 01:52:00 UTC
Report from Felix Kühling:

This commit broke the build for me, even with your later fix of the link
order. The problem is that os/xprintf.c is built with -ansi -pedantic.
In this case va_copy is not defined as a macro by stdarg.h (using
gcc-3.3.4 and gcc-3.3.5) and is missing when Xorg is finally linked. 

va_copy not being defined is not a new problem, I found it in an older
build log I had hanging around. The error was never found before because
no other object linked into Xorg used Xprintf before this commit. So
xprintf.o (from libos.a) was never linked. I'm not sure what the proper
fix would be. Either change the compiler flags or avoid using va_copy in
xprintf.c.

--

according to bug #347 va_copy is defined as __va_copy
Comment 8 Alexander Gottwald 2005-02-03 01:55:21 UTC
Created attachment 1827 [details] [review]
check for va_copy not being defined and use __va_copy if available

extends attachment #1370 [details] [review]
Comment 9 Alexander Gottwald 2005-02-03 01:59:37 UTC
Comment on attachment 1827 [details] [review]
check for va_copy not being defined and use __va_copy if available

commited to head

/cvs/xorg/xc/ChangeLog,v  <--  ChangeLog
new revision: 1.751; previous revision: 1.750
/cvs/xorg/xc/programs/Xserver/os/xprintf.c,v  <-- 
programs/Xserver/os/xprintf.c
new revision: 1.3; previous revision: 1.2
Comment 10 Alexander Gottwald 2005-02-03 02:00:11 UTC
marking as fixed
Comment 11 Alexander Gottwald 2005-02-03 02:50:27 UTC
XFree has added a similar function Xasprintf. maybe renaming Xprintf to
Xasprintf would be a good idea to have similar functions names and make porting
of code easier


Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.