Add license file
[platform/upstream/libxml2.git] / xmlstring.c
index 910f244..cc85777 100644 (file)
@@ -3,7 +3,7 @@
  *
  * This module provides various utility functions for manipulating
  * the xmlChar* type. All functions named xmlStr* have been moved here
- * from the parser.c file (their original home). 
+ * from the parser.c file (their original home).
  *
  * See Copyright for the status of this software.
  *
@@ -40,7 +40,7 @@
 xmlChar *
 xmlStrndup(const xmlChar *cur, int len) {
     xmlChar *ret;
-    
+
     if ((cur == NULL) || (len < 0)) return(NULL);
     ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
@@ -85,7 +85,7 @@ xmlChar *
 xmlCharStrndup(const char *cur, int len) {
     int i;
     xmlChar *ret;
-    
+
     if ((cur == NULL) || (len < 0)) return(NULL);
     ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
@@ -170,7 +170,7 @@ xmlStrEqual(const xmlChar *str1, const xmlChar *str2) {
  * @name:  the localname of the QName
  * @str:  the second xmlChar *
  *
- * Check if a QName is Equal to a given string 
+ * Check if a QName is Equal to a given string
  *
  * Returns 1 if they are equal, 0 if they are different
  */
@@ -340,7 +340,7 @@ xmlStrchr(const xmlChar *str, xmlChar val) {
 const xmlChar *
 xmlStrstr(const xmlChar *str, const xmlChar *val) {
     int n;
-    
+
     if (str == NULL) return(NULL);
     if (val == NULL) return(NULL);
     n = xmlStrlen(val);
@@ -368,7 +368,7 @@ xmlStrstr(const xmlChar *str, const xmlChar *val) {
 const xmlChar *
 xmlStrcasestr(const xmlChar *str, const xmlChar *val) {
     int n;
-    
+
     if (str == NULL) return(NULL);
     if (val == NULL) return(NULL);
     n = xmlStrlen(val);
@@ -396,7 +396,7 @@ xmlStrcasestr(const xmlChar *str, const xmlChar *val) {
 xmlChar *
 xmlStrsub(const xmlChar *str, int start, int len) {
     int i;
-    
+
     if (str == NULL) return(NULL);
     if (start < 0) return(NULL);
     if (len < 0) return(NULL);
@@ -457,6 +457,8 @@ xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
         return(xmlStrndup(add, len));
 
     size = xmlStrlen(cur);
+    if (size < 0)
+        return(NULL);
     ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
         xmlErrMemory(NULL, NULL);
@@ -484,14 +486,19 @@ xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) {
     int size;
     xmlChar *ret;
 
-    if (len < 0)
+    if (len < 0) {
         len = xmlStrlen(str2);
+        if (len < 0)
+            return(NULL);
+    }
     if ((str2 == NULL) || (len == 0))
         return(xmlStrdup(str1));
     if (str1 == NULL)
         return(xmlStrndup(str2, len));
 
     size = xmlStrlen(str1);
+    if (size < 0)
+        return(NULL);
     ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar));
     if (ret == NULL) {
         xmlErrMemory(NULL, NULL);
@@ -519,7 +526,7 @@ xmlStrcat(xmlChar *cur, const xmlChar *add) {
     const xmlChar *p = add;
 
     if (add == NULL) return(cur);
-    if (cur == NULL) 
+    if (cur == NULL)
         return(xmlStrdup(add));
 
     while (*p != 0) p++; /* non input consuming */
@@ -537,20 +544,20 @@ xmlStrcat(xmlChar *cur, const xmlChar *add) {
  *
  * Returns the number of characters written to @buf or -1 if an error occurs.
  */
-int XMLCDECL 
-xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) {
+int XMLCDECL
+xmlStrPrintf(xmlChar *buf, int len, const char *msg, ...) {
     va_list args;
     int ret;
-    
+
     if((buf == NULL) || (msg == NULL)) {
         return(-1);
     }
-    
+
     va_start(args, msg);
     ret = vsnprintf((char *) buf, len, (const char *) msg, args);
     va_end(args);
     buf[len - 1] = 0; /* be safe ! */
-    
+
     return(ret);
 }
 
@@ -565,17 +572,17 @@ xmlStrPrintf(xmlChar *buf, int len, const xmlChar *msg, ...) {
  *
  * Returns the number of characters written to @buf or -1 if an error occurs.
  */
-int 
-xmlStrVPrintf(xmlChar *buf, int len, const xmlChar *msg, va_list ap) {
+int
+xmlStrVPrintf(xmlChar *buf, int len, const char *msg, va_list ap) {
     int ret;
-    
+
     if((buf == NULL) || (msg == NULL)) {
         return(-1);
     }
-    
+
     ret = vsnprintf((char *) buf, len, (const char *) msg, ap);
     buf[len - 1] = 0; /* be safe ! */
-    
+
     return(ret);
 }
 
@@ -837,8 +844,8 @@ xmlUTF8Strsize(const xmlChar *utf, int len) {
             break;
         if ( (ch = *ptr++) & 0x80)
             while ((ch<<=1) & 0x80 ) {
-                ptr++;
                if (*ptr == 0) break;
+                ptr++;
            }
     }
     return (ptr - utf);
@@ -858,7 +865,7 @@ xmlChar *
 xmlUTF8Strndup(const xmlChar *utf, int len) {
     xmlChar *ret;
     int i;
-    
+
     if ((utf == NULL) || (len < 0)) return(NULL);
     i = xmlUTF8Strsize(utf, len);
     ret = (xmlChar *) xmlMallocAtomic((i + 1) * sizeof(xmlChar));
@@ -980,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"