diff --git a/SOURCES/swig-3.0.12-Add-missing-checks-for-failures-in-calls-to-PyUnicod.patch b/SOURCES/swig-3.0.12-Add-missing-checks-for-failures-in-calls-to-PyUnicod.patch
new file mode 100644
index 0000000..7050452
--- /dev/null
+++ b/SOURCES/swig-3.0.12-Add-missing-checks-for-failures-in-calls-to-PyUnicod.patch
@@ -0,0 +1,346 @@
+From b0e29fbdf31bb94b11cb8a7cc830b4a76467afa3 Mon Sep 17 00:00:00 2001
+From: William S Fulton
+# %module example
+#
+#-%include <std_string.i>
+#-
+# %inline %{
+#
+#-const char* non_utf8_c_str(void) {
+#+const char * non_utf8_c_str(void) {
+# return "h\xe9llo w\xc3\xb6rld";
+# }
+#
+#+void instring(const char *s) {
+#+ ...
+#+}
+#+
+# %}
+#
+#+When Python 3 strings are passed to the C/C++ layer, they are expected to be valid UTF8 Unicode strings too. +#+For example, when the instring method above is wrapped and called, any invalid UTF8 Unicode code strings +#+will result in a TypeError because the attempted conversion fails: +#+
+#+ +#++#+>>> example.instring('h\xe9llo') +#+>>> example.instring('h\udce9llo') +#+Traceback (most recent call last): +#+ File "<stdin>", line 1, in <module> +#+TypeError: in method 'instring', argument 1 of type 'char const *' +#+
+# In some cases, users may wish to instead handle all byte strings as bytes
+# objects in Python 3. This can be accomplished by adding
+#diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
+#index eba816382..014a38cae 100644
+#--- a/Doc/Manual/Varargs.html
+#+++ b/Doc/Manual/Varargs.html
+#@@ -529,8 +529,11 @@ like this:
+# SWIG_fail;
+# }
+# pystr = PyUnicode_AsUTF8String(pyobj);
+#+ if (!pystr) {
+#+ SWIG_fail;
+#+ }
+# str = strdup(PyBytes_AsString(pystr));
+#- Py_XDECREF(pystr);
+#+ Py_DECREF(pystr);
+# %#else
+# if (!PyString_Check(pyobj)) {
+# PyErr_SetString(PyExc_ValueError, "Expected a string");
+diff --git a/Examples/python/multimap/example.i b/Examples/python/multimap/example.i
+index 66c0f74c6..3ff5d52c0 100644
+--- a/Examples/python/multimap/example.i
++++ b/Examples/python/multimap/example.i
+@@ -39,7 +39,11 @@ extern int gcd(int x, int y);
+ %#if PY_VERSION_HEX >= 0x03000000
+ {
+ PyObject *utf8str = PyUnicode_AsUTF8String(s);
+- const char *cstr = PyBytes_AsString(utf8str);
++ const char *cstr;
++ if (!utf8str) {
++ SWIG_fail;
++ }
++ cstr = PyBytes_AsString(utf8str);
+ $2[i] = strdup(cstr);
+ Py_DECREF(utf8str);
+ }
+@@ -72,6 +76,9 @@ extern int gcdmain(int argc, char *argv[]);
+ SWIG_fail;
+ }
+ utf8str = PyUnicode_AsUTF8String($input);
++ if (!utf8str) {
++ SWIG_fail;
++ }
+ PyBytes_AsStringAndSize(utf8str, &cstr, &len);
+ $1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
+ $2 = (int)len;
+@@ -105,6 +112,9 @@ extern int count(char *bytes, int len, char c);
+ char *cstr;
+ Py_ssize_t len;
+ PyObject *utf8str = PyUnicode_AsUTF8String($input);
++ if (!utf8str) {
++ SWIG_fail;
++ }
+ PyBytes_AsStringAndSize(utf8str, &cstr, &len);
+ $1 = strncpy((char *)malloc(len+1), cstr, (size_t)len);
+ $2 = (int)len;
+diff --git a/Examples/test-suite/python/unicode_strings_runme.py b/Examples/test-suite/python/unicode_strings_runme.py
+index fa9c51437..39e93b0fc 100644
+--- a/Examples/test-suite/python/unicode_strings_runme.py
++++ b/Examples/test-suite/python/unicode_strings_runme.py
+@@ -25,3 +25,13 @@ if sys.version_info[0:2] < (3, 0):
+ check(unicode_strings.charstring(unicode("hello4")), "hello4")
+ unicode_strings.charstring(u"hell\xb05")
+ unicode_strings.charstring(u"hell\u00f66")
++
++low_surrogate_string = u"\udcff"
++try:
++ unicode_strings.instring(low_surrogate_string)
++ # Will succeed with Python 2
++except TypeError, e:
++ # Python 3 will fail the PyUnicode_AsUTF8String conversion resulting in a TypeError.
++ # The real error is actually:
++ # UnicodeEncodeError: 'utf-8' codec can't encode character '\udcff' in position 0: surrogates not allowed
++ pass
+diff --git a/Examples/test-suite/python_varargs_typemap.i b/Examples/test-suite/python_varargs_typemap.i
+index f05fb98eb..d809bf1fa 100644
+--- a/Examples/test-suite/python_varargs_typemap.i
++++ b/Examples/test-suite/python_varargs_typemap.i
+@@ -23,8 +23,11 @@
+ SWIG_fail;
+ }
+ pystr = PyUnicode_AsUTF8String(pyobj);
++ if (!pystr) {
++ SWIG_fail;
++ }
+ str = strdup(PyBytes_AsString(pystr));
+- Py_XDECREF(pystr);
++ Py_DECREF(pystr);
+ %#else
+ if (!PyString_Check(pyobj)) {
+ PyErr_SetString(PyExc_ValueError, "Expected a string");
+diff --git a/Examples/test-suite/unicode_strings.i b/Examples/test-suite/unicode_strings.i
+index 9be3748e6..e7266266e 100644
+--- a/Examples/test-suite/unicode_strings.i
++++ b/Examples/test-suite/unicode_strings.i
+@@ -20,4 +20,6 @@ char *charstring(char *s) {
+ return s;
+ }
+
++void instring(const char *s) {
++}
+ %}
+diff --git a/Lib/python/pyerrors.swg b/Lib/python/pyerrors.swg
+index fe7313554..463afae15 100644
+--- a/Lib/python/pyerrors.swg
++++ b/Lib/python/pyerrors.swg
+@@ -53,14 +53,17 @@ SWIG_Python_AddErrorMsg(const char* mesg)
+ PyObject *value = 0;
+ PyObject *traceback = 0;
+
+- if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback);
++ if (PyErr_Occurred())
++ PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+- char *tmp;
+ PyObject *old_str = PyObject_Str(value);
++ const char *tmp = SWIG_Python_str_AsChar(old_str);
+ PyErr_Clear();
+ Py_XINCREF(type);
+-
+- PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
++ if (tmp)
++ PyErr_Format(type, "%s %s", tmp, mesg);
++ else
++ PyErr_Format(type, "%s", mesg);
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(old_str);
+ Py_DECREF(value);
+diff --git a/Lib/python/pyhead.swg b/Lib/python/pyhead.swg
+index 55eb95a6d..2fa8b5b4c 100644
+--- a/Lib/python/pyhead.swg
++++ b/Lib/python/pyhead.swg
+@@ -38,14 +38,16 @@ SWIGINTERN char*
+ SWIG_Python_str_AsChar(PyObject *str)
+ {
+ #if PY_VERSION_HEX >= 0x03000000
+- char *cstr;
+- char *newstr;
+- Py_ssize_t len;
++ char *newstr = 0;
+ str = PyUnicode_AsUTF8String(str);
+- PyBytes_AsStringAndSize(str, &cstr, &len);
+- newstr = (char *) malloc(len+1);
+- memcpy(newstr, cstr, len+1);
+- Py_XDECREF(str);
++ if (str) {
++ char *cstr;
++ Py_ssize_t len;
++ PyBytes_AsStringAndSize(str, &cstr, &len);
++ newstr = (char *) malloc(len+1);
++ memcpy(newstr, cstr, len+1);
++ Py_XDECREF(str);
++ }
+ return newstr;
+ #else
+ return PyString_AsString(str);
+diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg
+index fe45ac941..826f8411b 100644
+--- a/Lib/python/pyinit.swg
++++ b/Lib/python/pyinit.swg
+@@ -84,10 +84,10 @@ swig_varlink_str(swig_varlinkobject *v) {
+
+ SWIGINTERN int
+ swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) {
+- char *tmp;
+ PyObject *str = swig_varlink_str(v);
++ const char *tmp = SWIG_Python_str_AsChar(str);
+ fprintf(fp,"Swig global variables ");
+- fprintf(fp,"%s\n", tmp = SWIG_Python_str_AsChar(str));
++ fprintf(fp,"%s\n", tmp ? tmp : "Invalid global variable");
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(str);
+ return 0;
+diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg
+index efc476613..430d3af18 100644
+--- a/Lib/python/pyrun.swg
++++ b/Lib/python/pyrun.swg
+@@ -1672,14 +1672,16 @@ SWIG_Python_AddErrMesg(const char* mesg, int infront)
+ PyObject *traceback = 0;
+ PyErr_Fetch(&type, &value, &traceback);
+ if (value) {
+- char *tmp;
+ PyObject *old_str = PyObject_Str(value);
++ const char *tmp = SWIG_Python_str_AsChar(old_str);
++ if (!tmp)
++ tmp = "Invalid error message";
+ Py_XINCREF(type);
+ PyErr_Clear();
+ if (infront) {
+- PyErr_Format(type, "%s %s", mesg, tmp = SWIG_Python_str_AsChar(old_str));
++ PyErr_Format(type, "%s %s", mesg, tmp);
+ } else {
+- PyErr_Format(type, "%s %s", tmp = SWIG_Python_str_AsChar(old_str), mesg);
++ PyErr_Format(type, "%s %s", tmp, mesg);
+ }
+ SWIG_Python_str_DelForPy3(tmp);
+ Py_DECREF(old_str);
+@@ -1805,6 +1807,8 @@ SWIG_Python_NonDynamicSetAttr(PyObject *obj, PyObject *name, PyObject *value) {
+ Py_INCREF(name);
+ } else {
+ encoded_name = PyUnicode_AsUTF8String(name);
++ if (!encoded_name)
++ return -1;
+ }
+ PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
+ Py_DECREF(encoded_name);
+diff --git a/Lib/python/pystrings.swg b/Lib/python/pystrings.swg
+index fd37855eb..301e0f3e1 100644
+--- a/Lib/python/pystrings.swg
++++ b/Lib/python/pystrings.swg
+@@ -16,6 +16,7 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+ %#endif
+ {
+ char *cstr; Py_ssize_t len;
++ int ret = SWIG_OK;
+ %#if PY_VERSION_HEX>=0x03000000
+ %#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
+ if (!alloc && cptr) {
+@@ -26,7 +27,10 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+ return SWIG_RuntimeError;
+ }
+ obj = PyUnicode_AsUTF8String(obj);
+- if(alloc) *alloc = SWIG_NEWOBJ;
++ if (!obj)
++ return SWIG_TypeError;
++ if (alloc)
++ *alloc = SWIG_NEWOBJ;
+ %#endif
+ PyBytes_AsStringAndSize(obj, &cstr, &len);
+ %#else
+@@ -64,6 +68,8 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+ %#endif
+ %#else
+ *cptr = SWIG_Python_str_AsChar(obj);
++ if (!*cptr)
++ ret = SWIG_TypeError;
+ %#endif
+ }
+ }
+@@ -71,7 +77,7 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+ %#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
+ Py_XDECREF(obj);
+ %#endif
+- return SWIG_OK;
++ return ret;
+ } else {
+ %#if defined(SWIG_PYTHON_2_UNICODE)
+ %#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
+@@ -84,6 +90,8 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+ return SWIG_RuntimeError;
+ }
+ obj = PyUnicode_AsUTF8String(obj);
++ if (!obj)
++ return SWIG_TypeError;
+ if (PyString_AsStringAndSize(obj, &cstr, &len) != -1) {
+ if (cptr) {
+ if (alloc) *alloc = SWIG_NEWOBJ;
+--
+2.21.1
+
diff --git a/SPECS/swig.spec b/SPECS/swig.spec
index 1e6db3b..c3e19f6 100644
--- a/SPECS/swig.spec
+++ b/SPECS/swig.spec
@@ -34,7 +34,7 @@
Summary: Connects C/C++/Objective C to some high-level programming languages
Name: swig
Version: 3.0.12
-Release: 18%{?dist}
+Release: 19%{?dist}
License: GPLv3+ and BSD
URL: http://swig.sourceforge.net/
Source0: http://downloads.sourceforge.net/project/swig/swig/swig-%{version}/swig-%{version}.tar.gz
@@ -61,6 +61,8 @@ Patch7: swig-3.0.12-Coverity-fix-issue-reported-for-SWIG_Python_FixMetho.patch
Patch8: swig-3.0.12-Fix-Coverity-issue-reported-for-setslice-pycontainer.patch
Patch9: swig-3.0.12-Coverity-fix-issue-reported-for-wrapper-argument-che.patch
Patch10: swig-3.0.12-Coverity-fix-issue-reported-for-SWIG_Python_ConvertF.patch
+# Add missing checks for failures in calls to PyUnicode_AsUTF8String (BZ#1804625)
+Patch11: swig-3.0.12-Add-missing-checks-for-failures-in-calls-to-PyUnicod.patch
BuildRequires: perl-interpreter, pcre-devel
%if %{python2lang}
@@ -169,6 +171,7 @@ in gdb.
%patch8 -p1
%patch9 -p1
%patch10 -p1
+%patch11 -p1
for all in CHANGES README; do
iconv -f ISO88591 -t UTF8 < $all > $all.new
@@ -332,6 +335,9 @@ install -pm 644 Tools/swig.gdb %{buildroot}%{_datadir}/%{name}/gdb
%{_datadir}/%{name}/gdb
%changelog
+* Fri Apr 03 2020 Jitka Plesnikova