Commit 502f6a6d authored by David Kilzer's avatar David Kilzer Committed by Daniel Veillard

More format string warnings with possible format string vulnerability

For https://bugzilla.gnome.org/show_bug.cgi?id=761029

adds a new xmlEscapeFormatString() function to escape composed format
strings
parent bdd66182
......@@ -9,6 +9,8 @@
#ifndef __XML_LIBXML_H__
#define __XML_LIBXML_H__
#include <libxml/xmlstring.h>
#ifndef NO_LARGEFILE_SOURCE
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
......@@ -93,6 +95,7 @@ int __xmlInitializeDict(void);
int __xmlRandom(void);
#endif
XMLPUBFUN xmlChar * XMLCALL xmlEscapeFormatString(xmlChar **msg);
int xmlNop(void);
#ifdef IN_LIBXML
......
......@@ -2215,7 +2215,8 @@ xmlRelaxNGGetErrorString(xmlRelaxNGValidErr err, const xmlChar * arg1,
snprintf(msg, 1000, "Unknown error code %d\n", err);
}
msg[1000 - 1] = 0;
return (xmlStrdup((xmlChar *) msg));
xmlChar *result = xmlCharStrdup(msg);
return (xmlEscapeFormatString(&result));
}
/**
......
......@@ -1769,7 +1769,7 @@ xmlSchemaFormatItemForReport(xmlChar **buf,
}
FREE_AND_NULL(str)
return (*buf);
return (xmlEscapeFormatString(buf));
}
/**
......@@ -2249,6 +2249,13 @@ xmlSchemaFormatNodeForError(xmlChar ** msg,
TODO
return (NULL);
}
/*
* xmlSchemaFormatItemForReport() also returns an escaped format
* string, so do this before calling it below (in the future).
*/
xmlEscapeFormatString(msg);
/*
* VAL TODO: The output of the given schema component is currently
* disabled.
......@@ -2476,11 +2483,13 @@ xmlSchemaSimpleTypeErr(xmlSchemaAbstractCtxtPtr actxt,
msg = xmlStrcat(msg, BAD_CAST " '");
if (type->builtInType != 0) {
msg = xmlStrcat(msg, BAD_CAST "xs:");
msg = xmlStrcat(msg, type->name);
} else
msg = xmlStrcat(msg,
xmlSchemaFormatQName(&str,
type->targetNamespace, type->name));
str = xmlStrdup(type->name);
} else {
const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
if (!str)
str = xmlStrdup(qName);
}
msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
msg = xmlStrcat(msg, BAD_CAST "'");
FREE_AND_NULL(str);
}
......@@ -2617,7 +2626,7 @@ xmlSchemaComplexTypeErr(xmlSchemaAbstractCtxtPtr actxt,
str = xmlStrcat(str, BAD_CAST ", ");
}
str = xmlStrcat(str, BAD_CAST " ).\n");
msg = xmlStrcat(msg, BAD_CAST str);
msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
FREE_AND_NULL(str)
} else
msg = xmlStrcat(msg, BAD_CAST "\n");
......@@ -3141,11 +3150,13 @@ xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
msg = xmlStrcat(msg, BAD_CAST " '");
if (type->builtInType != 0) {
msg = xmlStrcat(msg, BAD_CAST "xs:");
msg = xmlStrcat(msg, type->name);
} else
msg = xmlStrcat(msg,
xmlSchemaFormatQName(&str,
type->targetNamespace, type->name));
str = xmlStrdup(type->name);
} else {
const xmlChar *qName = xmlSchemaFormatQName(&str, type->targetNamespace, type->name);
if (!str)
str = xmlStrdup(qName);
}
msg = xmlStrcat(msg, xmlEscapeFormatString(&str));
msg = xmlStrcat(msg, BAD_CAST "'.");
FREE_AND_NULL(str);
}
......@@ -3158,7 +3169,9 @@ xmlSchemaPSimpleTypeErr(xmlSchemaParserCtxtPtr ctxt,
}
if (expected) {
msg = xmlStrcat(msg, BAD_CAST " Expected is '");
msg = xmlStrcat(msg, BAD_CAST expected);
xmlChar *expectedEscaped = xmlCharStrdup(expected);
msg = xmlStrcat(msg, xmlEscapeFormatString(&expectedEscaped));
FREE_AND_NULL(expectedEscaped);
msg = xmlStrcat(msg, BAD_CAST "'.\n");
} else
msg = xmlStrcat(msg, BAD_CAST "\n");
......
......@@ -987,5 +987,60 @@ xmlUTF8Strsub(const xmlChar *utf, int start, int len) {
return(xmlUTF8Strndup(utf, len));
}
/**
* xmlEscapeFormatString:
* @msg: a pointer to the string in which to escape '%' characters.
* Must be a heap-allocated buffer created by libxml2 that may be
* returned, or that may be freed and replaced.
*
* Replaces the string pointed to by 'msg' with an escaped string.
* Returns the same string with all '%' characters escaped.
*/
xmlChar *
xmlEscapeFormatString(xmlChar **msg)
{
xmlChar *msgPtr = NULL;
xmlChar *result = NULL;
xmlChar *resultPtr = NULL;
size_t count = 0;
size_t msgLen = 0;
size_t resultLen = 0;
if (!msg || !*msg)
return(NULL);
for (msgPtr = *msg; *msgPtr != '\0'; ++msgPtr) {
++msgLen;
if (*msgPtr == '%')
++count;
}
if (count == 0)
return(*msg);
resultLen = msgLen + count + 1;
result = (xmlChar *) xmlMallocAtomic(resultLen * sizeof(xmlChar));
if (result == NULL) {
/* Clear *msg to prevent format string vulnerabilities in
out-of-memory situations. */
xmlFree(*msg);
*msg = NULL;
xmlErrMemory(NULL, NULL);
return(NULL);
}
for (msgPtr = *msg, resultPtr = result; *msgPtr != '\0'; ++msgPtr, ++resultPtr) {
*resultPtr = *msgPtr;
if (*msgPtr == '%')
*(++resultPtr) = '%';
}
result[resultLen - 1] = '\0';
xmlFree(*msg);
*msg = result;
return *msg;
}
#define bottom_xmlstring
#include "elfgcchack.h"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment