From e4a48c7b1d1d62b1e8d2bca1c62f777bda496d4f Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Fri, 26 Aug 2011 14:21:35 +0200
Subject: [PATCH] utils: Fix UnescapeAndSplit parsing bug
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

If a value passed to UnescapeAndSplit ended with a backslash an
exception would be raised:

$ gnt-instance modify -H mem=x\\ inst1.example.com
[…]
    e2 = slist.pop(0)
IndexError: pop from empty list

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>
---
 lib/utils/text.py                  |  2 +-
 test/ganeti.utils.text_unittest.py | 14 +++++++++++++-
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/lib/utils/text.py b/lib/utils/text.py
index c51d7292c..e95c53787 100644
--- a/lib/utils/text.py
+++ b/lib/utils/text.py
@@ -343,7 +343,7 @@ def UnescapeAndSplit(text, sep=","):
     e1 = slist.pop(0)
     if e1.endswith("\\"):
       num_b = len(e1) - len(e1.rstrip("\\"))
-      if num_b % 2 == 1:
+      if num_b % 2 == 1 and slist:
         e2 = slist.pop(0)
         # here the backslashes remain (all), and will be reduced in
         # the next step
diff --git a/test/ganeti.utils.text_unittest.py b/test/ganeti.utils.text_unittest.py
index 2bc0c23b4..de7511ec8 100755
--- a/test/ganeti.utils.text_unittest.py
+++ b/test/ganeti.utils.text_unittest.py
@@ -298,7 +298,7 @@ class TestUnescapeAndSplit(unittest.TestCase):
 
   def setUp(self):
     # testing more that one separator for regexp safety
-    self._seps = [",", "+", "."]
+    self._seps = [",", "+", ".", ":"]
 
   def testSimple(self):
     a = ["a", "b", "c", "d"]
@@ -323,6 +323,18 @@ class TestUnescapeAndSplit(unittest.TestCase):
       b = ["a", "b\\" + sep + "c", "d"]
       self.failUnlessEqual(utils.UnescapeAndSplit(sep.join(a), sep=sep), b)
 
+  def testEscapeAtEnd(self):
+    for sep in self._seps:
+      self.assertEqual(utils.UnescapeAndSplit("\\", sep=sep), ["\\"])
+
+      a = ["a", "b\\", "c"]
+      b = ["a", "b" + sep + "c\\"]
+      self.assertEqual(utils.UnescapeAndSplit("%s\\" % sep.join(a), sep=sep), b)
+
+      a = ["\\" + sep, "\\" + sep, "c", "d\\.moo"]
+      b = [sep, sep, "c", "d.moo\\"]
+      self.assertEqual(utils.UnescapeAndSplit("%s\\" % sep.join(a), sep=sep), b)
+
 
 class TestCommaJoin(unittest.TestCase):
   def test(self):
-- 
GitLab