From 8650e166888997416fbef75883cd0b4570a0a6ef Mon Sep 17 00:00:00 2001 From: Aleš Raszka Date: Aug 26 2015 12:46:59 +0000 Subject: [PATCH 1/2] Decode .spec file with UTF-8 Resolves: bz#1242997 Signed-off-by: Aleš Raszka --- diff --git a/src/pyrpkg/__init__.py b/src/pyrpkg/__init__.py index 2d3d3db..68b466f 100644 --- a/src/pyrpkg/__init__.py +++ b/src/pyrpkg/__init__.py @@ -2301,7 +2301,16 @@ class Commands(object): # Create a list for unused patches unused = [] # Get the content of spec into memory for fast searching - spec = open(self.spec, 'r').read() + try: + spec = open(self.spec, 'r').read().decode('UTF-8') + except UnicodeDecodeError as error: + # when can't decode file, ignore chars and show warning + spec = open(self.spec, 'r').read().decode(encoding='UTF-8', errors='ignore') + line, offset = self._byte_offset_to_line_number(spec, error.start) + self.log.warning("\'%s\' codec can't decode byte in position %d:%d : %s" + % (error.encoding, line, offset, error.reason)) + except: + raise # Replace %{name} with the package name spec = spec.replace("%{name}", self.module_name) # Replace %{version} with the package version @@ -2317,6 +2326,17 @@ class Commands(object): unused.append(file) return unused + def _byte_offset_to_line_number(self, text, offset): + offset_inc = 0 + line_num = 1 + for line in text.split('\n'): + if offset_inc + len(line) + 1 > offset: + break + else: + offset_inc += len(line) + 1 + line_num += 1 + return [line_num, offset - offset_inc + 1] + def verify_files(self, builddir=None): """Run rpmbuild -bl on a module to verify the %files section From c9ce9d5485ad4503ae41d49fb332cd5e2a3dfa77 Mon Sep 17 00:00:00 2001 From: Ales Raszka Date: Sep 16 2015 14:59:54 +0000 Subject: [PATCH 2/2] Add test and docstring to byte offset convertor Signed-off-by: Ales Raszka --- diff --git a/src/pyrpkg/__init__.py b/src/pyrpkg/__init__.py index 68b466f..23b2c16 100644 --- a/src/pyrpkg/__init__.py +++ b/src/pyrpkg/__init__.py @@ -2309,8 +2309,6 @@ class Commands(object): line, offset = self._byte_offset_to_line_number(spec, error.start) self.log.warning("\'%s\' codec can't decode byte in position %d:%d : %s" % (error.encoding, line, offset, error.reason)) - except: - raise # Replace %{name} with the package name spec = spec.replace("%{name}", self.module_name) # Replace %{version} with the package version @@ -2327,6 +2325,11 @@ class Commands(object): return unused def _byte_offset_to_line_number(self, text, offset): + """ + Convert byte offset (given by e.g. DecodeError) to human readable + format (line number and char possition) + Return a list with line number and char offset + """ offset_inc = 0 line_num = 1 for line in text.split('\n'): diff --git a/test/commands/test_patch.py b/test/commands/test_patch.py new file mode 100644 index 0000000..18921f3 --- /dev/null +++ b/test/commands/test_patch.py @@ -0,0 +1,53 @@ +# -*- coding: utf-8 -*- +from . import CommandTestCase + + +class CommandPatchTestCase(CommandTestCase): + def setUp(self): + super(CommandPatchTestCase, self).setUp() + self.text_ascii = "Lorem ipsum dolor sit amet, consectetur elit.\n" \ + "Sed vel enim nec tortor posuere sodales sit amet mauris.\n" \ + "Duis ipsum dui, consectetur pretium a, vestibulum.\n"\ + "Nunc vel consectetur libero. Aenean , metus quis posuere\n" \ + "vulputate, purus metus fringilla, sit amet interdum tellus\n" + self.text_utf8 = "ěšč\n" \ + "ščř\n" \ + "ýáí" + + def test_byte_offset_first_line(self): + import pyrpkg + cmd = pyrpkg.Commands(self.path, self.lookaside, self.lookasidehash, + self.lookaside_cgi, self.gitbaseurl, + self.anongiturl, self.branchre, self.kojiconfig, + self.build_client, self.user, self.dist, + self.target, self.quiet) + line, offset = cmd._byte_offset_to_line_number(self.text_ascii, 10) + #10 byte offset mean line 1 and character 11 + self.assertEqual(line, 1) + self.assertEqual(offset, 11) + + def test_byte_offset_next_line(self): + import pyrpkg + cmd = pyrpkg.Commands(self.path, self.lookaside, self.lookasidehash, + self.lookaside_cgi, self.gitbaseurl, + self.anongiturl, self.branchre, self.kojiconfig, + self.build_client, self.user, self.dist, + self.target, self.quiet) + + line, offset = cmd._byte_offset_to_line_number(self.text_ascii, 46) + # 46 byte offset is first character on second line + self.assertEqual(line, 2) + self.assertEqual(offset, 1) + + def test_byte_offset_utf8(self): + import pyrpkg + cmd = pyrpkg.Commands(self.path, self.lookaside, self.lookasidehash, + self.lookaside_cgi, self.gitbaseurl, + self.anongiturl, self.branchre, self.kojiconfig, + self.build_client, self.user, self.dist, + self.target, self.quiet) + text = self.text_utf8.decode(encoding='UTF-8', errors='ignore') + line, offset = cmd._byte_offset_to_line_number(text, 9) + #9 byte offset mean line 3 and second character + self.assertEqual(line, 3) + self.assertEqual(offset, 2)