From 7cdd8027d13677185b301f849d42957e635ffa67 Mon Sep 17 00:00:00 2001
From: StefanBruens <stefan.bruens@rwth-aachen.de>
Date: Tue, 25 Sep 2018 21:56:36 +0200
Subject: [PATCH 006/127] firewall/core/io/*.py: Let SAX handle the encoding of
 XML files (#395)

SAX is able to determine the encoding of XML files itself if the file
contains a correct "encoding" pseudo attribute, e.g.:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>

For this to work, the file stream has to be opened in binary mode, and
the parser has to read the stream using a SAX InputStream, which
autodetects the encoding.

Fixes: #303
---
 src/firewall/core/io/direct.py   | 6 ++++--
 src/firewall/core/io/helper.py   | 6 ++++--
 src/firewall/core/io/icmptype.py | 6 ++++--
 src/firewall/core/io/ipset.py    | 6 ++++--
 src/firewall/core/io/service.py  | 6 ++++--
 src/firewall/core/io/zone.py     | 6 ++++--
 6 files changed, 24 insertions(+), 12 deletions(-)

diff --git a/src/firewall/core/io/direct.py b/src/firewall/core/io/direct.py
index 07e159da..b0c2cb52 100644
--- a/src/firewall/core/io/direct.py
+++ b/src/firewall/core/io/direct.py
@@ -360,9 +360,11 @@ class Direct(IO_Object):
         handler = direct_ContentHandler(self)
         parser = sax.make_parser()
         parser.setContentHandler(handler)
-        with open(self.filename, "r") as f:
+        with open(self.filename, "rb") as f:
+            source = sax.InputSource(None)
+            source.setByteStream(f)
             try:
-                parser.parse(f)
+                parser.parse(source)
             except sax.SAXParseException as msg:
                 raise FirewallError(errors.INVALID_TYPE,
                                     "Not a valid file: %s" % \
diff --git a/src/firewall/core/io/helper.py b/src/firewall/core/io/helper.py
index 4a2420dd..a5c81b9f 100644
--- a/src/firewall/core/io/helper.py
+++ b/src/firewall/core/io/helper.py
@@ -156,9 +156,11 @@ def helper_reader(filename, path):
     parser = sax.make_parser()
     parser.setContentHandler(handler)
     name = "%s/%s" % (path, filename)
-    with open(name, "r") as f:
+    with open(name, "rb") as f:
+        source = sax.InputSource(None)
+        source.setByteStream(f)
         try:
-            parser.parse(f)
+            parser.parse(source)
         except sax.SAXParseException as msg:
             raise FirewallError(errors.INVALID_HELPER,
                                 "not a valid helper file: %s" % \
diff --git a/src/firewall/core/io/icmptype.py b/src/firewall/core/io/icmptype.py
index 91b48867..32103c59 100644
--- a/src/firewall/core/io/icmptype.py
+++ b/src/firewall/core/io/icmptype.py
@@ -121,9 +121,11 @@ def icmptype_reader(filename, path):
     parser = sax.make_parser()
     parser.setContentHandler(handler)
     name = "%s/%s" % (path, filename)
-    with open(name, "r") as f:
+    with open(name, "rb") as f:
+        source = sax.InputSource(None)
+        source.setByteStream(f)
         try:
-            parser.parse(f)
+            parser.parse(source)
         except sax.SAXParseException as msg:
             raise FirewallError(errors.INVALID_ICMPTYPE,
                                 "not a valid icmptype file: %s" % \
diff --git a/src/firewall/core/io/ipset.py b/src/firewall/core/io/ipset.py
index 0670677b..8cc6a1f9 100644
--- a/src/firewall/core/io/ipset.py
+++ b/src/firewall/core/io/ipset.py
@@ -390,9 +390,11 @@ def ipset_reader(filename, path):
     parser = sax.make_parser()
     parser.setContentHandler(handler)
     name = "%s/%s" % (path, filename)
-    with open(name, "r") as f:
+    with open(name, "rb") as f:
+        source = sax.InputSource(None)
+        source.setByteStream(f)
         try:
-            parser.parse(f)
+            parser.parse(source)
         except sax.SAXParseException as msg:
             raise FirewallError(errors.INVALID_IPSET,
                                 "not a valid ipset file: %s" % \
diff --git a/src/firewall/core/io/service.py b/src/firewall/core/io/service.py
index c04d612e..487d5ba3 100644
--- a/src/firewall/core/io/service.py
+++ b/src/firewall/core/io/service.py
@@ -219,9 +219,11 @@ def service_reader(filename, path):
     parser = sax.make_parser()
     parser.setContentHandler(handler)
     name = "%s/%s" % (path, filename)
-    with open(name, "r") as f:
+    with open(name, "rb") as f:
+        source = sax.InputSource(None)
+        source.setByteStream(f)
         try:
-            parser.parse(f)
+            parser.parse(source)
         except sax.SAXParseException as msg:
             raise FirewallError(errors.INVALID_SERVICE,
                                 "not a valid service file: %s" % \
diff --git a/src/firewall/core/io/zone.py b/src/firewall/core/io/zone.py
index c048c867..05368e9c 100644
--- a/src/firewall/core/io/zone.py
+++ b/src/firewall/core/io/zone.py
@@ -696,9 +696,11 @@ def zone_reader(filename, path, no_check_name=False):
     parser = sax.make_parser()
     parser.setContentHandler(handler)
     name = "%s/%s" % (path, filename)
-    with open(name, "r") as f:
+    with open(name, "rb") as f:
+        source = sax.InputSource(None)
+        source.setByteStream(f)
         try:
-            parser.parse(f)
+            parser.parse(source)
         except sax.SAXParseException as msg:
             raise FirewallError(errors.INVALID_ZONE,
                                 "not a valid zone file: %s" % \
-- 
2.19.1

