Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

xmlpatch use of csvreader causes too many arguments if a string contains a comma #133

Open
glennehrlich opened this issue May 18, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@glennehrlich
Copy link

glennehrlich commented May 18, 2024

Things like elements or comments with commas in them will cause the csv reader used in the patch code to incorrectly parse the patch line, causing a TypeError complaining about more positional arguments than expected. Not sure what the right way to configure csvreader is for this, but it does seem that there are some options that may help with this.

Anyway, test data that's similar to one of the unit tests:

glenn@ubuntu:~/tmp/sv030/test$ python3.11 --version
Python 3.11.6+
glenn@ubuntu:~/tmp/sv030/test$ xmldiff --version
xmldiff 2.7.0
glenn@ubuntu:~/tmp/sv030/test$ xmlpatch --version
xmldiff 2.7.0
glenn@ubuntu:~/tmp/sv030/test$ cat test1.xml
<root><anode/></root>
glenn@ubuntu:~/tmp/sv030/test$ cat test2.xml
<root><anode/>foo,bar</root>
glenn@ubuntu:~/tmp/sv030/test$ xmldiff test1.xml test2.xml > patch
glenn@ubuntu:~/tmp/sv030/test$ xmlpatch patch test1.xml
Traceback (most recent call last):
  File "/home/glenn/.local/bin/xmlpatch", line 8, in <module>
    sys.exit(patch_command())
             ^^^^^^^^^^^^^^^
  File "/home/glenn/.local/lib/python3.11/site-packages/xmldiff/main.py", line 254, in patch_command
    result = patch_file(args.patchfile, args.xmlfile, args.diff_encoding)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/glenn/.local/lib/python3.11/site-packages/xmldiff/main.py", line 223, in patch_file
    tree = patch_tree(actions, tree)
           ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/glenn/.local/lib/python3.11/site-packages/xmldiff/main.py", line 199, in patch_tree
    return patcher.patch(actions, tree)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/glenn/.local/lib/python3.11/site-packages/xmldiff/patch.py", line 25, in patch
    for action in actions:
  File "/home/glenn/.local/lib/python3.11/site-packages/xmldiff/patch.py", line 112, in parse
    yield self.make_action(line)
          ^^^^^^^^^^^^^^^^^^^^^^
  File "/home/glenn/.local/lib/python3.11/site-packages/xmldiff/patch.py", line 127, in make_action
    return method(*params)
           ^^^^^^^^^^^^^^^
TypeError: DiffParser._handle_update_text_after() takes 3 positional arguments but 4 were given
glenn@ubuntu:~/tmp/sv030/test$
@glennehrlich
Copy link
Author

Forgot the contents of the patch file:

glenn@ubuntu:~/tmp/sv030/test$ cat patch
[update-text-after, /root/anode[1], "foo,bar"]
glenn@ubuntu:~/tmp/sv030/test$ 

@cdbassett
Copy link

cdbassett commented Jul 3, 2024

I don't have permission to create a pull request, but here is a patch that fixes it for me (note that this fixes the formatter, so existing "patch" files will have to be recreated before they will work):

[PATCH] fix issue #133 - writing comma separated values in DiffFormatter does not take commas in the values into account. By using the csv module to write and not just read, this is fixed.

---
 xmldiff/formatting.py | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/xmldiff/formatting.py b/xmldiff/formatting.py
index 640ec15..5e42fb8 100644
--- a/xmldiff/formatting.py
+++ b/xmldiff/formatting.py
@@ -1,8 +1,10 @@
 import json
 import re
+import io
 
 from collections import namedtuple
 from copy import deepcopy
+from csv import writer
 from lxml import etree
 from xmldiff.diff_match_patch import diff_match_patch
 from xmldiff import utils
@@ -742,7 +744,11 @@ class DiffFormatter(BaseFormatter):
     def handle_action(self, action):
         action_type = type(action)
         method = getattr(self, "_handle_" + action_type.__name__)
-        return ", ".join(method(action))
+
+        with io.StringIO() as csvfile:
+            w = writer(csvfile)
+            w.writerow(method(action))
+            return csvfile.getvalue().strip()
 
     def _handle_DeleteAttrib(self, action):
         return "delete-attribute", action.node, action.name

--
2.41.0.windows.3

@regebro
Copy link
Contributor

regebro commented Sep 18, 2024

Unfortunately, it's not quite that simple. I think my attempt of misusing the CSV module to do things that are not strictly CSV is the problem here.

@regebro regebro added the bug Something isn't working label Sep 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants