Re: [PATCH 2/5] pylibfdt: Proper handling of bytes/unicode strings and octal literals

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Hello.

On 07/16/2018 01:33 AM, Simon Glass wrote:
Hi,

On 12 July 2018 at 19:01, David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> wrote:
On Thu, Jul 12, 2018 at 04:10:42PM +0200, frenzy@xxxxxxxxx wrote:
From: Lumir Balhar <lbalhar@xxxxxxxxxx>

Signed-off-by: Lumir Balhar <lbalhar@xxxxxxxxxx>
---
  pylibfdt/libfdt.i       | 14 +++++++++++---
  tests/pylibfdt_tests.py | 17 ++++++++++-------
  2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i
index aed5390..88d443d 100644
--- a/pylibfdt/libfdt.i
+++ b/pylibfdt/libfdt.i
@@ -624,7 +624,7 @@ class Fdt:
          Raises:
              FdtException if no parent found or other error occurs
          """
-        val = val.encode('utf-8') + '\0'
+        val = val.encode('utf-8') + b'\0'
          return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name,
                                       val, len(val)), quiet)

@@ -749,12 +749,20 @@ typedef uint32_t fdt32_t;
       if (!$1)
               $result = Py_None;
       else
-             $result = Py_BuildValue("s#", $1, *arg4);
+        %#if PY_VERSION_HEX >= 0x03000000
+            $result = Py_BuildValue("y#", $1, *arg4);
+        %#else
+            $result = Py_BuildValue("s#", $1, *arg4);
+        %#endif
  }

  /* typemap used for fdt_setprop() */
  %typemap(in) (const void *val) {
-    $1 = PyString_AsString($input);   /* char *str */
+    %#if PY_VERSION_HEX >= 0x03000000
+        $1 = PyBytes_AsString($input);
+    %#else
+        $1 = PyString_AsString($input);   /* char *str */
+    %#endif
  }

  /* typemaps used for fdt_next_node() */
diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py
index 9f3e55a..e1204f8 100644
--- a/tests/pylibfdt_tests.py
+++ b/tests/pylibfdt_tests.py
@@ -69,7 +69,10 @@ TEST_VALUE64_1 = (TEST_VALUE64_1H << 32) | TEST_VALUE64_1L

  TEST_STRING_1 = 'hello world'
  TEST_STRING_2 = 'hi world'
-TEST_STRING_3 = u'unicode ' + unichr(467)
+try:
+    TEST_STRING_3 = u'unicode ' + unichr(467)
+except NameError:
+    TEST_STRING_3 = u'unicode ' + chr(467)

Doing this with a try/except seems pretty yucky.  What about:

TEST_STRING_# = u'unicode \u01d3'
I agree it's better to avoid exceptions when handling normal cases. I
worry that it makes things non-deterministic.

If the above doesn't work in some cases then perhaps we can check the
Python version.
You are right. New patch attached.

It's such a shame that Python has then backwards-incompatible changes,
but I suppose that has been discussed to death elsewhere, and we have
no alternative.

  def get_err(err_code):
@@ -92,7 +95,7 @@ def _ReadFdt(fname):
      Returns:
          Fdt bytearray suitable for passing to libfdt functions
      """
-    return libfdt.Fdt(open(fname).read())
+    return libfdt.Fdt(open(fname, mode='rb').read())
Actually a correct fix regardless of python 2/3 issues.
and perhaps could be a separate patch.

Regards,
Simon

>From 21889171fabc1bb19c06ad3742e5b34bb8f6dfdd Mon Sep 17 00:00:00 2001
From: Lumir Balhar <lbalhar@xxxxxxxxxx>
Date: Mon, 9 Jul 2018 12:40:09 +0200
Subject: [PATCH 2/5] pylibfdt: Proper handling of bytes/unicode strings and
 octal literals

Signed-off-by: Lumir Balhar <lbalhar@xxxxxxxxxx>
---
 pylibfdt/libfdt.i       | 14 +++++++++++---
 tests/pylibfdt_tests.py | 16 ++++++++--------
 2 files changed, 19 insertions(+), 11 deletions(-)

diff --git a/pylibfdt/libfdt.i b/pylibfdt/libfdt.i
index fc53a8c..3e25430 100644
--- a/pylibfdt/libfdt.i
+++ b/pylibfdt/libfdt.i
@@ -669,7 +669,7 @@ class Fdt(FdtRo):
         Raises:
             FdtException if no parent found or other error occurs
         """
-        val = val.encode('utf-8') + '\0'
+        val = val.encode('utf-8') + b'\0'
         return check_err(fdt_setprop(self._fdt, nodeoffset, prop_name,
                                      val, len(val)), quiet)
 
@@ -1041,12 +1041,20 @@ typedef uint32_t fdt32_t;
 	if (!$1)
 		$result = Py_None;
 	else
-		$result = Py_BuildValue("s#", $1, *arg4);
+        %#if PY_VERSION_HEX >= 0x03000000
+            $result = Py_BuildValue("y#", $1, *arg4);
+        %#else
+            $result = Py_BuildValue("s#", $1, *arg4);
+        %#endif
 }
 
 /* typemap used for fdt_setprop() */
 %typemap(in) (const void *val) {
-    $1 = PyString_AsString($input);   /* char *str */
+    %#if PY_VERSION_HEX >= 0x03000000
+        $1 = PyBytes_AsString($input);
+    %#else
+        $1 = PyString_AsString($input);   /* char *str */
+    %#endif
 }
 
 /* typemap used for fdt_add_reservemap_entry() */
diff --git a/tests/pylibfdt_tests.py b/tests/pylibfdt_tests.py
index e61fda9..fc0181e 100644
--- a/tests/pylibfdt_tests.py
+++ b/tests/pylibfdt_tests.py
@@ -69,7 +69,7 @@ TEST_ADDR_2H = 0
 TEST_ADDR_2L = 123456789
 TEST_ADDR_2 = (TEST_ADDR_2H << 32) | TEST_ADDR_2L
 TEST_SIZE_2H = 0
-TEST_SIZE_2L = 010000
+TEST_SIZE_2L = 0x10000
 TEST_SIZE_2 = (TEST_SIZE_2H << 32) | TEST_SIZE_2L
 
 TEST_VALUE_1 = 0xdeadbeef
@@ -84,7 +84,7 @@ PHANDLE_2 = 0x2001
 
 TEST_STRING_1 = 'hello world'
 TEST_STRING_2 = 'hi world'
-TEST_STRING_3 = u'unicode ' + unichr(467)
+TEST_STRING_3 = u'unicode \u01d3'
 
 
 def get_err(err_code):
@@ -107,7 +107,7 @@ def _ReadFdt(fname):
     Returns:
         Fdt bytearray suitable for passing to libfdt functions
     """
-    return libfdt.Fdt(open(fname).read())
+    return libfdt.Fdt(open(fname, mode='rb').read())
 
 class PyLibfdtBasicTests(unittest.TestCase):
     """Test class for basic pylibfdt access functions
@@ -146,7 +146,7 @@ class PyLibfdtBasicTests(unittest.TestCase):
     def testBadFdt(self):
         """Check that a filename provided accidentally is not accepted"""
         with self.assertRaises(FdtException) as e:
-            fdt = libfdt.Fdt('a string')
+            fdt = libfdt.Fdt(b'a string')
         self.assertEquals(e.exception.err, -libfdt.BADMAGIC)
 
     def testSubnodeOffset(self):
@@ -221,7 +221,7 @@ class PyLibfdtBasicTests(unittest.TestCase):
         poffset = self.fdt.first_property_offset(root)
         prop = self.fdt.get_property_by_offset(poffset)
         self.assertEquals(prop.name, 'compatible')
-        self.assertEquals(prop, 'test_tree1\0')
+        self.assertEquals(prop, b'test_tree1\0')
 
         with self.assertRaises(FdtException) as e:
             self.fdt.get_property_by_offset(-2)
@@ -234,7 +234,7 @@ class PyLibfdtBasicTests(unittest.TestCase):
         """Check that we can read the contents of a property by name"""
         root = self.fdt.path_offset('/')
         value = self.fdt.getprop(root, "compatible")
-        self.assertEquals(value, 'test_tree1\0')
+        self.assertEquals(value, b'test_tree1\0')
         self.assertEquals(-libfdt.NOTFOUND, self.fdt.getprop(root, 'missing',
                                                              QUIET_NOTFOUND))
 
@@ -244,7 +244,7 @@ class PyLibfdtBasicTests(unittest.TestCase):
 
         node = self.fdt.path_offset('/subnode@1/subsubnode')
         value = self.fdt.getprop(node, "compatible")
-        self.assertEquals(value, 'subsubnode1\0subsubnode\0')
+        self.assertEquals(value, b'subsubnode1\0subsubnode\0')
 
     def testStrError(self):
         """Check that we can get an error string"""
@@ -404,7 +404,7 @@ class PyLibfdtBasicTests(unittest.TestCase):
         self.assertEquals(2, self.fdt.num_mem_rsv())
         self.assertEquals([ 0xdeadbeef00000000, 0x100000],
                           self.fdt.get_mem_rsv(0))
-        self.assertEquals([123456789, 010000], self.fdt.get_mem_rsv(1))
+        self.assertEquals([123456789, 0o10000], self.fdt.get_mem_rsv(1))
 
     def testEmpty(self):
         """Test that we can create an empty tree"""
-- 
2.17.1


[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux