You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by fu...@apache.org on 2019/02/21 00:22:51 UTC

svn commit: r1854006 - in /subversion/branches/swig-py3/subversion/bindings/swig/python: libsvn_swig_py/swigutil_py.c tests/client.py

Author: futatuki
Date: Thu Feb 21 00:22:50 2019
New Revision: 1854006

URL: http://svn.apache.org/viewvc?rev=1854006&view=rev
Log:
On branch swig-py3: Allow str return to svn_client_get_commit_log3_t callback

* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c:
 (svn_swig_py_get_commit_log_func): Allow result as unicode object

* subversion/bindings/swig/python/tests/client.py:
 (SubversionClientTestCase.make_log_message_func): New helper function
 (SubversionClientTestCase.test_get_commit_log3_callback_accept_unicode):
  New test case
 (SubversionClientTestCase.test_get_commit_log3_callback_unicode_error):
  New test case

Modified:
    subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
    subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1854006&r1=1854005&r2=1854006&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Thu Feb 21 00:22:50 2019
@@ -3335,23 +3335,34 @@ svn_error_t *svn_swig_py_get_commit_log_
 
   if (result == Py_None)
     {
-      Py_DECREF(result);
       *log_msg = NULL;
       err = SVN_NO_ERROR;
     }
   else if (PyBytes_Check(result))
     {
       *log_msg = apr_pstrdup(pool, PyBytes_AsString(result));
-      Py_DECREF(result);
       err = SVN_NO_ERROR;
     }
+  else if (PyUnicode_Check(result))
+    {
+      /* PyStr_AsUTF8() may cause UnicodeEncodeError,
+         but apr_pstrdup() allows NULL for s */
+      if ((*log_msg = apr_pstrdup(pool, PyStr_AsUTF8(result))) == NULL)
+        {
+          err = callback_exception_error();
+        }
+      else
+        {
+          err = SVN_NO_ERROR;
+        }
+    }
   else
     {
-      Py_DECREF(result);
-      err = callback_bad_return_error("Not a bytes object");
+      err = callback_bad_return_error("Not a bytes or str object");
     }
+  Py_DECREF(result);
 
- finished:
+finished:
   svn_swig_py_release_py_lock();
   return err;
 }

Modified: subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py
URL: http://svn.apache.org/viewvc/subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py?rev=1854006&r1=1854005&r2=1854006&view=diff
==============================================================================
--- subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py (original)
+++ subversion/branches/swig-py3/subversion/bindings/swig/python/tests/client.py Thu Feb 21 00:22:50 2019
@@ -33,7 +33,7 @@ class SubversionClientTestCase(unittest.
   """Test cases for the basic SWIG Subversion client layer"""
 
   def assert_all_instances_of(self, iterable, instancetype):
-    """"Asserts that all object from iterable are an instance of instancetype."""
+    """Asserts that all object from iterable are an instance of instancetype."""
 
     self.assertTrue(not [x for x in iterable if not isinstance(x, instancetype)])
 
@@ -42,6 +42,12 @@ class SubversionClientTestCase(unittest.
     self.log_message_func_calls += 1
     return b"Test log message"
 
+  def make_log_message_func(self, message):
+    def generic_log_message_func(items, pool):
+      self.log_message_func_calls += 1
+      return message
+    return generic_log_message_func
+
   def log_receiver(self, changed_paths, revision, author, date, message, pool):
     """ Function to receive log messages retrieved by client.log3(). """
     self.log_message = message
@@ -210,6 +216,31 @@ class SubversionClientTestCase(unittest.
     self.assertEqual(commit_info.revision, 13)
     self.assertEqual(self.log_message_func_calls, 1)
 
+  def test_get_commit_log3_callback_accept_unicode(self):
+    """Test svn_client_get_commit_log3_t callback wrapper accept unicode as return value"""
+    directory = urljoin(self.repos_uri+b"/", b"dir1")
+    # override callback function which returns commit log as unicode
+    unicode_log_message_func = self.make_log_message_func(u"Test log message")
+    self.client_ctx.log_msg_baton3 = unicode_log_message_func
+
+    commit_info = client.mkdir3((directory,), 1, {b'customprop':b'value'},
+                                self.client_ctx)
+    self.assertEqual(commit_info.revision, 13)
+    self.assertEqual(self.log_message_func_calls, 1)
+
+  def test_get_commit_log3_callback_unicode_error(self):
+    """Test svn_client_get_commit_log3_t callback wrapper handles UnicodeEncodeError correctly"""
+    directory = urljoin(self.repos_uri+b"/", b"dir1")
+    # override callback function which returns commit log as unicode
+    # which contains surrogate escaped character
+    bogus_log_message_func = self.make_log_message_func(u"Test \udc6cog"
+                                                        u" message")
+    self.client_ctx.log_msg_baton3 = bogus_log_message_func
+
+    with self.assertRaises(UnicodeEncodeError):
+      commit_info = client.mkdir3((directory,), 1, {b'customprop':b'value'},
+                                  self.client_ctx)
+
   def test_log3_url(self):
     """Test svn_client_log3 on a file:// URL"""
     directory = urljoin(self.repos_uri+b"/", b"trunk/dir1")