From 035e9e01d495827588b32fdd1d44e3a9547985ea Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 4 Feb 2020 16:17:25 -0500 Subject: [PATCH] Fix crash in Python backend when using empty docstrings --- ...-backend-when-using-empty-docstrings.patch | 88 +++++++++++++++++++ swig.spec | 9 +- 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 swig-4.0.1-Fix-crash-in-Python-backend-when-using-empty-docstrings.patch diff --git a/swig-4.0.1-Fix-crash-in-Python-backend-when-using-empty-docstrings.patch b/swig-4.0.1-Fix-crash-in-Python-backend-when-using-empty-docstrings.patch new file mode 100644 index 0000000..c9b5ce7 --- /dev/null +++ b/swig-4.0.1-Fix-crash-in-Python-backend-when-using-empty-docstrings.patch @@ -0,0 +1,88 @@ +From e14532ce52a654768cc4010e9e18e1a0a4d965db Mon Sep 17 00:00:00 2001 +From: Vadim Zeitlin +Date: Sat, 25 Jan 2020 17:06:20 +0100 +Subject: [PATCH] Fix crash in Python backend when using empty docstrings + +Due to confusion in build_combined_docstring(), we could call +DohDelete() on the "feature:docstring" string, which resulted in a crash +when trying to use it later. + +Fix this and simplify the code at the same time by ensuring that we +always use a copy of "feature:docstring" if it's not empty or don't use +it at all if it's empty -- like this we don't have to check for its +length each time before using it. + +Closes #1648. +--- + Examples/test-suite/autodoc.i | 9 +++++++++ + Examples/test-suite/python/autodoc_runme.py | 2 ++ + Source/Modules/python.cxx | 15 +++++++++++---- + 3 files changed, 22 insertions(+), 4 deletions(-) + +diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i +index 9f4365ee1c..efc7201553 100644 +--- a/Examples/test-suite/autodoc.i ++++ b/Examples/test-suite/autodoc.i +@@ -183,3 +183,12 @@ const int PROCESS_DEFAULT_VALUE = 17; + typedef long int some_type; + int process_complex_defval(int val = PROCESS_DEFAULT_VALUE, int factor = some_type(-1)) { return val*factor; } + %} ++ ++// Test for empty docstring, which should be ignored. ++%feature("docstring") "" ++ ++%inline %{ ++struct a_structure{ ++ char my_array[1]; ++}; ++%} +diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py +index 6002d49fec..7bc918644d 100644 +--- a/Examples/test-suite/python/autodoc_runme.py ++++ b/Examples/test-suite/python/autodoc_runme.py +@@ -279,3 +279,5 @@ def check(got, expected, expected_builtin=None, skip=False): + check(inspect.getdoc(process4), "process4(int _from=0, int _in=1, int var=2) -> int") + + check(inspect.getdoc(process_complex_defval), "process_complex_defval(val=PROCESS_DEFAULT_VALUE, factor=some_type(-1)) -> int") ++ ++check(inspect.getdoc(a_structure.__init__), "__init__(a_structure self) -> a_structure", None, skip) +diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx +index 1dbedad26a..f6b47be244 100644 +--- a/Source/Modules/python.cxx ++++ b/Source/Modules/python.cxx +@@ -1484,8 +1484,15 @@ class PYTHON:public Language { + + String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) { + String *docstr = Getattr(n, "feature:docstring"); +- if (docstr && Len(docstr)) { +- docstr = Copy(docstr); ++ if (docstr) { ++ // Simplify the code below by just ignoring empty docstrings. ++ if (!Len(docstr)) ++ docstr = NULL; ++ else ++ docstr = Copy(docstr); ++ } ++ ++ if (docstr) { + char *t = Char(docstr); + if (*t == '{') { + Delitem(docstr, 0); +@@ -1496,7 +1503,7 @@ class PYTHON:public Language { + if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) { + String *autodoc = make_autodoc(n, ad_type, low_level); + if (autodoc && Len(autodoc) > 0) { +- if (docstr && Len(docstr)) { ++ if (docstr) { + Append(autodoc, "\n"); + Append(autodoc, docstr); + } +@@ -1509,7 +1516,7 @@ class PYTHON:public Language { + Delete(autodoc); + } + +- if (!docstr || !Len(docstr)) { ++ if (!docstr) { + if (doxygen) { + docstr = Getattr(n, "python:docstring"); + if (!docstr && doxygenTranslator->hasDocumentation(n)) { diff --git a/swig.spec b/swig.spec index c396cb1..996ead8 100644 --- a/swig.spec +++ b/swig.spec @@ -53,7 +53,7 @@ Summary: Connects C/C++/Objective C to some high-level programming languages Name: swig Version: 4.0.1 -Release: 6%{?dist} +Release: 7%{?dist} License: GPLv3+ and BSD URL: http://swig.sourceforge.net/ Source0: http://downloads.sourceforge.net/project/swig/swig/swig-%{version}/swig-%{version}.tar.gz @@ -72,6 +72,9 @@ Patch1: swig-4.0.1-Fix-code-generated-for-Ruby-global-variables.patch # Add support for Ruby 2.7 # https://github.com/swig/swig/pull/1692 Patch2: swig-4.0.1-Add-support-for-Ruby-2.7.patch +# Fix crash in Python backend when using empty docstrings +# https://github.com/swig/swig/pull/1710 +Patch3: swig-4.0.1-Fix-crash-in-Python-backend-when-using-empty-docstrings.patch BuildRequires: perl-interpreter, pcre-devel %if %{python2lang} @@ -175,6 +178,7 @@ in gdb. %patch0 -p1 -b .isystem %patch1 -p1 -b .global %patch2 -p1 -b .ruby27 +%patch3 -p1 -b .python for all in CHANGES README; do iconv -f ISO88591 -t UTF8 < $all > $all.new @@ -347,6 +351,9 @@ install -pm 644 Tools/swig.gdb %{buildroot}%{_datadir}/%{name}/gdb %{_datadir}/%{name}/gdb %changelog +* Tue Feb 04 2020 Michael Jeanson - 4.0.1-7 +- Fix crash in Python backend when using empty docstrings + * Fri Jan 31 2020 Fedora Release Engineering - 4.0.1-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild