GNOME Bugzilla – Bug 52538
xmlGetVarStr cores on non-VNSPRINTF systems
Last modified: 2009-08-15 18:40:50 UTC
libxml version: 2.3.5 Test OS version: SunOS 5.5.1 (although any non-vnsprintf system would have a similar problem. While running the validation tests on libxml 2.3.5, xmllint cored in xmlGetVarSTr. The problem has to do with the following code (about line 158): str = (char *) xmlMalloc(100); if (str == NULL) return(NULL); size = 100; length = 0; while (1) { left = size - length; /* Try to print in the allocated space. */ #ifdef HAVE_VSNPRINTF chars = vsnprintf(str + length, left, msg, args); #else chars = vsprintf(str + length, msg, args); #endif /* If that worked, we're done. */ if ((chars > -1) && (chars < left )) break; /* Else try again with more space. */ if (chars > -1) /* glibc 2.1 */ size += chars + 1; /* precisely what is needed */ else /* glibc 2.0 */ size += 100; if ((larger = (char *) xmlRealloc(str, size)) == NULL) { xmlFree(str); return(NULL); } str = larger; } The base problem is that 100 characters is no where near enough for many messages going through this call. On a system where vnsprintf is available, the coded loop works fine. However on a non-vnsprintf system, the xmlRealloc call can cause a segmentation violation. Since there is no vnsprintf, the two options are 1) implement a vnsprintf in libxml or 2) use larger buffers for non vnsprintf systems. Option 2 is more consistent with the rest of the library, so my proposed change would be to select the appropriate buffer size above the original malloc call as follows: #ifdef HAVE_VSNPRINTF size = 256; #else /* No VSNPRINTF, hope this is long enough */ size = 2048; #endif str = (char *) xmlMalloc(size); And then delete the setting of size to 100 after the malloc call. Granted a buffer size of 2048 only pushes the problem out, but it solves the test case problem (actually so would 256 characters, but many other validation error messages could easily be more than 256 characters).
I have tried to get rid for good of this string functions portability and the security nightmare of using sprintf or vsprintf. Basically I will follow your approach i.e. embedd rimplementation of the missing functions, except I will try to use the trio library of string functions: http://sourceforge.net/projects/ctrio/ Main argument for selecting those is that Bjorn Reese is one of the coauthors and hence we have pretty good chance to get things fixed promptly in case of troubles. I have put an updated test distribution at: ftp://xmlsoft.org/test/libxml2-2.3.5.tar.gz and i would really like feedback on the portability of the resulting code. This is a rather large change and I would prefer early feedback before making a full release with this, thanks in advance, Daniel
After quick report it seems that this works on a number of Solaris, HP-UX and AIX systems, both new and ancient, looks good but won't be closed until more people test the fix once released. Daniel