You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by cm...@apache.org on 2018/12/10 13:35:08 UTC

svn commit: r1848577 - in /subversion/trunk/subversion/bindings/swig: include/svn_types.swg python/libsvn_swig_py/swigutil_py.c python/tests/repository.py

Author: cmpilato
Date: Mon Dec 10 13:35:07 2018
New Revision: 1848577

URL: http://svn.apache.org/viewvc?rev=1848577&view=rev
Log:
swig-py: Followup to r1848425, moving the bulk of the stream
conversion logic into libsvn_swig_py (instead of having it duplicated
dozens of times in generated code).

* subversion/bindings/swig/include/svn_types.swg
  (%typemap(in) svn_stream_t *WRAPPED_STREAM): Move the logic of
    handling multiple stream-like input types...

* subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
  (svn_swig_py_make_stream): ...to here.
  (parse_fn3_set_fulltext): Raise a callback exception if stream
    construction fails.

* subversion/bindings/swig/python/tests/repository.py
  (test_parse_fns3_invalid_set_fulltext): New test.

Patch by: Yasuhito FUTATSUKI <futatuki at yf.bsdclub.org>
          Jun Omae
          (Tweaked by me.)

Modified:
    subversion/trunk/subversion/bindings/swig/include/svn_types.swg
    subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
    subversion/trunk/subversion/bindings/swig/python/tests/repository.py

Modified: subversion/trunk/subversion/bindings/swig/include/svn_types.swg
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/include/svn_types.swg?rev=1848577&r1=1848576&r2=1848577&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/include/svn_types.swg (original)
+++ subversion/trunk/subversion/bindings/swig/include/svn_types.swg Mon Dec 10 13:35:07 2018
@@ -945,56 +945,9 @@ svn_ ## TYPE ## _swig_rb_closed(VALUE se
         $1 = NULL;
     }
     else {
-        PyObject *libsvn_core;
-        PyObject *py_stream_t;
-        libsvn_core = PyImport_ImportModule("libsvn.core");
-        if (PyErr_Occurred()) {
-            Py_XDECREF(libsvn_core);
-            SWIG_fail;
-        }
-        py_stream_t = PyObject_GetAttrString(libsvn_core, "svn_stream_t");
-        if (PyErr_Occurred()) {
-            Py_XDECREF(py_stream_t);
-            Py_DECREF(libsvn_core);
-            SWIG_fail;
-        }
-        if (PyObject_IsInstance($input, py_stream_t)) {
-            $1 = (svn_stream_t *)svn_swig_py_must_get_ptr(
-                                    $input, $1_descriptor, $argnum);
-            if (PyErr_Occurred()) {
-                Py_DECREF(py_stream_t);
-                Py_DECREF(libsvn_core);
-                SWIG_fail;
-            }
-            Py_DECREF(py_stream_t);
-            Py_DECREF(libsvn_core);
-        }
-        else if (PyObject_HasAttrString($input, "_stream")){
-            PyObject *_stream = PyObject_GetAttrString($input, "_stream");
-            if (PyObject_IsInstance(_stream, py_stream_t)) {
-                $1 = (svn_stream_t *)svn_swig_py_must_get_ptr(
-                                        _stream, $1_descriptor,
-                                        $argnum);
-                if (PyErr_Occurred()) {
-                    PyErr_Clear();
-                    $1 = NULL;
-                }
-                Py_DECREF(_stream);
-                Py_DECREF(py_stream_t);
-                Py_DECREF(libsvn_core);
-            }
-        }
+        $1 = svn_swig_py_make_stream ($input, _global_pool);
         if ($1 == NULL) {
-            if (   PyObject_HasAttrString($input, "read")
-                || PyObject_HasAttrString($input, "write")) {
-                $1 = svn_swig_py_make_stream ($input, _global_pool);
-            }
-            else {
-                PyErr_SetString(PyExc_TypeError,
-                                "expecting a svn_stream_t"
-                                " or file like object");
-                SWIG_fail;
-            }
+            SWIG_fail;
         }
     }
 }

Modified: subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c?rev=1848577&r1=1848576&r2=1848577&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c (original)
+++ subversion/trunk/subversion/bindings/swig/python/libsvn_swig_py/swigutil_py.c Mon Dec 10 13:35:07 2018
@@ -2293,8 +2293,8 @@ static svn_error_t *parse_fn3_set_fullte
                                            void *node_baton)
 {
   item_baton *ib = node_baton;
-  PyObject *result;
-  svn_error_t *err;
+  PyObject *result = NULL;
+  svn_error_t *err = SVN_NO_ERROR;
 
   svn_swig_py_acquire_py_lock();
 
@@ -2316,14 +2316,17 @@ static svn_error_t *parse_fn3_set_fullte
       /* create a stream from the IO object. it will increment the
          reference on the 'result'. */
       *stream = svn_swig_py_make_stream(result, ib->pool);
+      if (*stream == NULL)
+        {
+          err = callback_exception_error();
+          goto finished;
+        }
     }
 
   /* if the handler returned an IO object, svn_swig_py_make_stream() has
      incremented its reference counter. If it was None, it is discarded. */
-  Py_DECREF(result);
-  err = SVN_NO_ERROR;
-
- finished:
+finished:
+  Py_XDECREF(result);
   svn_swig_py_release_py_lock();
   return err;
 }
@@ -2575,17 +2578,59 @@ svn_swig_py_stream_destroy(void *py_io)
 svn_stream_t *
 svn_swig_py_make_stream(PyObject *py_io, apr_pool_t *pool)
 {
-  svn_stream_t *stream;
-
-  stream = svn_stream_create(py_io, pool);
-  svn_stream_set_read2(stream, read_handler_pyio, NULL);
-  svn_stream_set_write(stream, write_handler_pyio);
-  svn_stream_set_close(stream, close_handler_pyio);
-  apr_pool_cleanup_register(pool, py_io, svn_swig_py_stream_destroy,
-                            apr_pool_cleanup_null);
-  Py_INCREF(py_io);
+  PyObject *libsvn_core = NULL;
+  PyObject *py_stream_t = NULL;
+  PyObject *_stream = NULL;
+  svn_stream_t *result = NULL;
+  swig_type_info *typeinfo = svn_swig_TypeQuery("svn_stream_t *");
+
+  libsvn_core = PyImport_ImportModule("libsvn.core");
+  if (PyErr_Occurred()) {
+    goto finished;
+  }
+  py_stream_t = PyObject_GetAttrString(libsvn_core, "svn_stream_t");
+  if (PyErr_Occurred()) {
+    goto finished;
+  }
+  if (PyObject_IsInstance(py_io, py_stream_t)) {
+    result = (svn_stream_t *)svn_swig_py_must_get_ptr(py_io, typeinfo, 0);
+    if (PyErr_Occurred()) {
+      result = NULL;
+      goto finished;
+    }
+  }
+  else if (PyObject_HasAttrString(py_io, "_stream")) {
+    _stream = PyObject_GetAttrString(py_io, "_stream");
+    if (PyObject_IsInstance(_stream, py_stream_t)) {
+      result = (svn_stream_t *)svn_swig_py_must_get_ptr(_stream, typeinfo, 0);
+      if (PyErr_Occurred()) {
+        result = NULL;
+        goto finished;
+      }
+    }
+  }
+  if (result == NULL) {
+    if (!PyObject_HasAttrString(py_io, "read")
+        && !PyObject_HasAttrString(py_io, "write")) {
+      PyErr_SetString(PyExc_TypeError,
+                      "expecting a svn_stream_t or file like object");
+      goto finished;
+    }
+    result = svn_stream_create(py_io, pool);
+    svn_stream_set_read2(result, read_handler_pyio, NULL);
+    svn_stream_set_write(result, write_handler_pyio);
+    svn_stream_set_close(result, close_handler_pyio);
+    apr_pool_cleanup_register(pool, py_io, svn_swig_py_stream_destroy,
+                              apr_pool_cleanup_null);
+    Py_INCREF(py_io);
+  }
+
+finished:
+  Py_XDECREF(_stream);
+  Py_XDECREF(py_stream_t);
+  Py_XDECREF(libsvn_core);
 
-  return stream;
+  return result;
 }
 
 PyObject *

Modified: subversion/trunk/subversion/bindings/swig/python/tests/repository.py
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/swig/python/tests/repository.py?rev=1848577&r1=1848576&r2=1848577&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/swig/python/tests/repository.py (original)
+++ subversion/trunk/subversion/bindings/swig/python/tests/repository.py Mon Dec 10 13:35:07 2018
@@ -231,6 +231,21 @@ class SubversionRepositoryTestCase(unitt
     # the comparison list gets too long.
     self.assertEqual(dsp.ops[:len(expected_list)], expected_list)
 
+  def test_parse_fns3_invalid_set_fulltext(self):
+    class DumpStreamParserSubclass(DumpStreamParser):
+      def set_fulltext(self, node_baton):
+        DumpStreamParser.set_fulltext(self, node_baton)
+        return 42
+    stream = open(os.path.join(os.path.dirname(sys.argv[0]),
+                               "trac/versioncontrol/tests/svnrepos.dump"))
+    try:
+      dsp = DumpStreamParserSubclass()
+      ptr, baton = repos.make_parse_fns3(dsp)
+      self.assertRaises(TypeError, repos.parse_dumpstream3,
+                        stream, ptr, baton, False, None)
+    finally:
+      stream.close()
+
   def test_get_logs(self):
     """Test scope of get_logs callbacks"""
     logs = []