]> wimlib.net Git - wimlib/blobdiff - src/xmlproc.c
xmlproc: fix buffer enlargement logic
[wimlib] / src / xmlproc.c
index 48569ff87f9fbc7461c63762596bc90d7236a8a3..8ce193e93028045716f090233f028ce93a67d359 100644 (file)
@@ -20,7 +20,7 @@
  * details.
  *
  * You should have received a copy of the GNU Lesser General Public License
- * along with this file; if not, see http://www.gnu.org/licenses/.
+ * along with this file; if not, see https://www.gnu.org/licenses/.
  */
 
 #ifdef HAVE_CONFIG_H
@@ -318,13 +318,20 @@ is_name_char(tchar c)
                (c >= '0' && c <= '9') || c == '-' || c == '.';
 }
 
+/* Allow characters used in element "paths"; see do_xml_path_walk() */
+static inline bool
+is_path_char(tchar c)
+{
+       return c == '/' || c == '[' || c == ']';
+}
+
 bool
-xml_legal_name(const tchar *p)
+xml_legal_path(const tchar *p)
 {
-       if (!is_name_start_char(*p))
+       if (!is_name_start_char(*p) && !is_path_char(*p))
                return false;
        for (p = p + 1; *p; p++) {
-               if (!is_name_char(*p))
+               if (!is_name_char(*p) && !is_path_char(*p))
                        return false;
        }
        return true;
@@ -334,7 +341,8 @@ bool
 xml_legal_value(const tchar *p)
 {
        for (; *p; p++) {
-               if (*p < 0x20 && !is_whitespace(*p))
+               /* Careful: tchar can be signed. */
+               if (*p > 0 && *p < 0x20 && !is_whitespace(*p))
                        return false;
        }
        return true;
@@ -541,7 +549,7 @@ parse_element(const tchar **pp, struct xml_node *parent, int depth,
        CHECK(*p == '<');
        p++;
        name_start = p;
-       while (!is_whitespace(*p) && *p != '>' && *p != '\0')
+       while (!is_whitespace(*p) && *p != '>' && *p != '/' && *p != '\0')
                p++;
        name_len = p - name_start;
        CHECK(name_len > 0);
@@ -657,7 +665,8 @@ static void
 xml_write(struct xml_out_buf *buf, const tchar *str, size_t len)
 {
        if (buf->count + len + 1 > buf->capacity) {
-               size_t new_capacity = max(buf->capacity * 2, 4096);
+               size_t new_capacity = max3(buf->count + len + 1,
+                                          buf->capacity * 2, 4096);
                tchar *new_buf = REALLOC(buf->buf,
                                         new_capacity * sizeof(str[0]));
                if (!new_buf) {