michaelrsweet / mxml

Tiny XML library.
https://www.msweet.org/mxml
Apache License 2.0
428 stars 157 forks source link

mxmlSetWrapMargin causes errors and does not work properly #76

Closed michaelrsweet closed 16 years ago

michaelrsweet commented 16 years ago

Version: 2.5 Original reporter: Michael Sweet

1) When disabling line wrapping by calling mxmlSetWrapMargin(0) then calling mxmlSaveString() or mxmlSaveAllocString() will result in errors.

2) When setting line wrapping by calling, for example, mxmlSetWrapMargin(1024) then calling mxmlSaveString() or mxmlSaveAllocString() to get a string representation, newlines have been added much earlier in the string than 1024. The wrapping doesn't seem to change based on the mxmlSetWrapMargin() call.

Here is the sample program I used for testing:

include

include

include

include "mxml.h"

void error_cb (const char *string) { fprintf (stderr, "ERROR: %s\n", string); }

const char whitespace_cb (mxml_node_t node, int where) { return NULL; }

int main (int argc, char *argv) { mxml_node_t xmldoc;
mxml_node_t node; char xmlstr; char xmlbuf[8192]; int rv;

mxmlSetErrorCallback (error_cb);

// This does not work, errors will be returned from the mxmlSave* routines mxmlSetWrapMargin (0);

// This does not work, strings are wrapped early? //mxmlSetWrapMargin (1024);

xmldoc = mxmlNewXML ("1.0");

node = mxmlNewElement (xmldoc, "Root");

mxmlElementSetAttr (node, "Attribute", "Value");

if ( ! (rv = mxmlSaveString (xmldoc, xmlbuf, sizeof(xmlbuf), whitespace_cb)) ) { fprintf (stderr, "Error converting to XML\n"); return 1; } printf ("Return value :%d\n", rv); printf ("%s\n", xmlbuf);

if ( ! (xmlstr = mxmlSaveAllocString (xmldoc, whitespace_cb)) ) { fprintf (stderr, "Error converting to XML\n"); return 1; } printf ("%s\n", xmlstr);

mxmlRelease (xmldoc);

if ( xmlstr ) free (xmlstr);

return 0; }

michaelrsweet commented 16 years ago

Original reporter: Michael Sweet

The errors seem to be related to the usage of mxmlNewXML() and the initial standard XML element: <?xml version="1.0"?>.

If I create a root element using mxmlNewElement(MXML_NO_PARENT,...) instead, the usage of mxmlSetWrapMargin(0) does not cause errors. The example program still outputs wrapped XML when, for example, mxmlSetWrapMargin(1024) is called.

michaelrsweet commented 16 years ago

Original reporter: Michael Sweet

For STR #76, error occurs when mxmlSetWrapMargin(0):

This problem is original from: mxml_write_node(), which prefers newline for <?xml ?> line, and force col = global->wrap, col is easy to overflow if global->wrap = 2147483647.

It is easy to patch the bug, we need only to modify mxml_write_node() as follows: /==============================================================================/

/*

static int / O - Column or -1 on error / mxml_write_node(mxml_node_t node, / I - Node to write / void p, / I - File to write to / mxml_save_cb_t cb, / I - Whitespace callback / int col, / I - Current column / _mxml_putc_cb_t putc_cb,/ I - Output callback / _mxml_global_t global)/ I - Global data / { int i, / Looping var / width; / Width of attr + value / mxml_attr_t attr; / Current attribute / char s[255]; / Temporary string /

while (node != NULL) { /*

michaelrsweet commented 16 years ago

Original reporter: Michael Sweet

See attached patch...

michaelrsweet commented 16 years ago

Original reporter: Michael Sweet

Fixed in Subversion repository.

michaelrsweet commented 16 years ago

"str76.patch":

Index: mxml-file.c
===================================================================
--- mxml-file.c (revision 350)
+++ mxml-file.c (working copy)
@@ -606,22 +606,19 @@
 /*
  * 'mxmlSetWrapMargin()' - Set the the wrap margin when saving XML data.
  *
- * Wrapping is disabled when "column" is <= 0.
+ * Wrapping is disabled when "column" is 0.
  *
  * @since Mini-XML 2.3@
  */

 void
-mxmlSetWrapMargin(int column)      /* I - Column for wrapping */
+mxmlSetWrapMargin(int column)      /* I - Column for wrapping, 0 to disable wrapping */
 {
   _mxml_global_t *global = _mxml_global();
                    /* Global data */

-  if (column <= 0)
-    global->wrap = 2147483647;
-  else
-    global->wrap = column;
+  global->wrap = column;
 }

@@ -2804,13 +2801,6 @@
        for (ptr = node->value.element.name; *ptr; ptr ++)
          if ((*putc_cb)(*ptr, p) < 0)
            return (-1);
-
-           /*
-       * Prefer a newline for whitespace after ?xml...
-       */
-
-            if (!strncmp(node->value.element.name, "?xml", 4))
-              col = global->wrap;
      }
      else if (mxml_write_name(node->value.element.name, p, putc_cb) < 0)
        return (-1);
@@ -2826,7 +2816,7 @@
        if (attr->value)
          width += strlen(attr->value) + 3;

-       if ((col + width) > global->wrap)
+       if (global->wrap > 0 && (col + width) > global->wrap)
        {
          if ((*putc_cb)('\n', p) < 0)
            return (-1);
@@ -2931,7 +2921,7 @@
       case MXML_INTEGER :
      if (node->prev)
      {
-       if (col > global->wrap)
+       if (global->wrap > 0 && col > global->wrap)
        {
          if ((*putc_cb)('\n', p) < 0)
            return (-1);
@@ -2961,7 +2951,7 @@
       case MXML_REAL :
      if (node->prev)
      {
-       if (col > global->wrap)
+       if (global->wrap > 0 && col > global->wrap)
        {
          if ((*putc_cb)('\n', p) < 0)
            return (-1);
@@ -2984,7 +2974,7 @@
       case MXML_TEXT :
      if (node->value.text.whitespace && col > 0)
      {
-       if (col > global->wrap)
+       if (global->wrap > 0 && col > global->wrap)
        {
          if ((*putc_cb)('\n', p) < 0)
            return (-1);