Compare commits

...
Sign in to create a new pull request.

1 commit

Author SHA1 Message Date
Jitka Plesnikova
2ef779ad6b Fix seg fault passing invalid unicode values to std::string (rhbz#2318762) 2024-12-02 14:44:40 +01:00
3 changed files with 392 additions and 1 deletions

View file

@ -0,0 +1,140 @@
From 32afafda3366841a2c3610f4ad87774881eef3ae Mon Sep 17 00:00:00 2001
From: William S Fulton <wsf@fultondesigns.co.uk>
Date: Sun, 20 Oct 2024 12:43:43 +0100
Subject: [PATCH] Add li_std_string runtime test
---
.../test-suite/python/li_std_string_runme.py | 121 ++++++++++++++++++
1 file changed, 121 insertions(+)
create mode 100644 Examples/test-suite/python/li_std_string_runme.py
diff --git a/Examples/test-suite/python/li_std_string_runme.py b/Examples/test-suite/python/li_std_string_runme.py
new file mode 100644
index 000000000..70f428193
--- /dev/null
+++ b/Examples/test-suite/python/li_std_string_runme.py
@@ -0,0 +1,121 @@
+from li_std_string import *
+
+def check(condition):
+ if not condition:
+ raise RuntimeError
+
+# Checking expected use of %typemap(in) std::string {}
+test_value("Fee")
+
+# Checking expected result of %typemap(out) std::string {}
+check(test_value("Fi") == "Fi")
+
+# Verify type-checking for %typemap(in) std::string {}
+exceptionRaised = False
+try:
+ test_value(0)
+except TypeError:
+ exceptionRaised = True
+check(exceptionRaised)
+
+# Checking expected use of %typemap(in) const std::string & {}
+test_const_reference("Fo")
+
+# Checking expected result of %typemap(out) const std::string& {}
+check(test_const_reference("Fum") == "Fum")
+
+# Verify type-checking for %typemap(in) const std::string & {}
+exceptionRaised = False
+try:
+ test_const_reference(0)
+except TypeError:
+ exceptionRaised = True
+check(exceptionRaised)
+
+#
+# Input and output typemaps for pointers and non-const references to
+# std::string are *not* supported; the following tests confirm
+# that none of these cases are slipping through.
+#
+
+exceptionRaised = False
+try:
+ test_pointer("foo")
+except TypeError:
+ exceptionRaised = True
+check(exceptionRaised)
+
+result = test_pointer_out()
+check(not isinstance(result, str))
+
+exceptionRaised = False
+try:
+ test_const_pointer("bar")
+except TypeError:
+ exceptionRaised = True
+check(exceptionRaised)
+
+result = test_const_pointer_out()
+check(not isinstance(result, str))
+
+exceptionRaised = False
+try:
+ test_reference("foo")
+except TypeError:
+ exceptionRaised = True
+check(exceptionRaised)
+
+result = test_reference_out()
+check(not isinstance(result, str))
+
+
+# Member Strings
+myStructure = Structure()
+if myStructure.MemberString2 != "member string 2":
+ raise RuntimeError
+s = "Hello"
+myStructure.MemberString2 = s
+if myStructure.MemberString2 != s:
+ raise RuntimeError
+if myStructure.ConstMemberString != "const member string":
+ raise RuntimeError
+
+
+if cvar.Structure_StaticMemberString2 != "static member string 2":
+ raise RuntimeError
+cvar.Structure_StaticMemberString2 = s
+if cvar.Structure_StaticMemberString2 != s:
+ raise RuntimeError
+if Structure.ConstStaticMemberString != "const static member string":
+ raise RuntimeError
+
+
+if test_reference_input("hello") != "hello":
+ raise RuntimeError
+s = test_reference_inout("hello")
+if s != "hellohello":
+ raise RuntimeError
+if test_reference_output() != "output":
+ raise RuntimeError
+
+
+if stdstring_empty() != "":
+ raise RuntimeError
+
+if c_empty() != "":
+ raise RuntimeError
+
+
+if c_null() != None:
+ raise RuntimeError
+
+
+if get_null(c_null()) != None:
+ raise RuntimeError
+
+
+if get_null(c_empty()) != "non-null":
+ raise RuntimeError
+
+if get_null(stdstring_empty()) != "non-null":
+ raise RuntimeError
--
2.47.0

View file

@ -0,0 +1,244 @@
From d06382ec2a48b9e93a06c7cef1f09bc6fa344fca Mon Sep 17 00:00:00 2001
From: William S Fulton <wsf@fultondesigns.co.uk>
Date: Sun, 20 Oct 2024 13:39:11 +0100
Subject: [PATCH] Fix seg fault passing invalid unicode values to std::string
Problem reported as starting with python-3.13.
Due to error not being cleared before calling Python C APIs.
The alternative could have been to ensure SWIG_AsCharPtrAndSize
never returns with a pending error (not that easy).
Closes #3051
---
# CHANGES.current | 4 ++
.../test-suite/python/li_std_string_runme.py | 66 ++++++++++++-------
Lib/python/pytypemaps.swg | 3 +
Lib/typemaps/std_strings.swg | 8 +--
Lib/typemaps/swigtypemaps.swg | 6 ++
5 files changed, 56 insertions(+), 31 deletions(-)
#diff --git a/CHANGES.current b/CHANGES.current
#index 96a299fa6..568f88086 100644
#--- a/CHANGES.current
#+++ b/CHANGES.current
#@@ -7,6 +7,10 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
# Version 4.3.0 (in progress)
# ===========================
#
#+2024-10-20: wsfulton
#+ #3051 Fix seg fault passing invalid unicode values when expecting a
#+ std::string type - fix for python-3.13.
#+
# 2024-10-19: olly
# [ruby] Documentation comments now use `true` and `false` for bool
# parameter default values, instead of `True` and `False` (which are
diff --git a/Examples/test-suite/python/li_std_string_runme.py b/Examples/test-suite/python/li_std_string_runme.py
index 70f428193..1a57529e1 100644
--- a/Examples/test-suite/python/li_std_string_runme.py
+++ b/Examples/test-suite/python/li_std_string_runme.py
@@ -1,9 +1,25 @@
+import sys
from li_std_string import *
def check(condition):
if not condition:
raise RuntimeError
+# Bad Unicode input check
+# This check is run first to check that %error_clear is called the first time SWIG_AsPtr_std_string()
+# is called setting the descriptor singleton (by calling SWIG_TypeQuery()).
+# Bug https://github.com/swig/swig/issues/3051.
+exceptionRaised = False
+try:
+ if sys.version_info[0:2] < (3, 0):
+ v = u"./\uDCFC.conf"
+ else:
+ v = "./\uDCFC.conf"
+ test_value(v)
+except TypeError:
+ exceptionRaised = True
+check(exceptionRaised)
+
# Checking expected use of %typemap(in) std::string {}
test_value("Fee")
@@ -13,9 +29,9 @@ check(test_value("Fi") == "Fi")
# Verify type-checking for %typemap(in) std::string {}
exceptionRaised = False
try:
- test_value(0)
+ test_value(0)
except TypeError:
- exceptionRaised = True
+ exceptionRaised = True
check(exceptionRaised)
# Checking expected use of %typemap(in) const std::string & {}
@@ -27,9 +43,9 @@ check(test_const_reference("Fum") == "Fum")
# Verify type-checking for %typemap(in) const std::string & {}
exceptionRaised = False
try:
- test_const_reference(0)
+ test_const_reference(0)
except TypeError:
- exceptionRaised = True
+ exceptionRaised = True
check(exceptionRaised)
#
@@ -40,9 +56,9 @@ check(exceptionRaised)
exceptionRaised = False
try:
- test_pointer("foo")
+ test_pointer("foo")
except TypeError:
- exceptionRaised = True
+ exceptionRaised = True
check(exceptionRaised)
result = test_pointer_out()
@@ -50,9 +66,9 @@ check(not isinstance(result, str))
exceptionRaised = False
try:
- test_const_pointer("bar")
+ test_const_pointer("bar")
except TypeError:
- exceptionRaised = True
+ exceptionRaised = True
check(exceptionRaised)
result = test_const_pointer_out()
@@ -60,9 +76,9 @@ check(not isinstance(result, str))
exceptionRaised = False
try:
- test_reference("foo")
+ test_reference("foo")
except TypeError:
- exceptionRaised = True
+ exceptionRaised = True
check(exceptionRaised)
result = test_reference_out()
@@ -72,50 +88,50 @@ check(not isinstance(result, str))
# Member Strings
myStructure = Structure()
if myStructure.MemberString2 != "member string 2":
- raise RuntimeError
+ raise RuntimeError
s = "Hello"
myStructure.MemberString2 = s
if myStructure.MemberString2 != s:
- raise RuntimeError
+ raise RuntimeError
if myStructure.ConstMemberString != "const member string":
- raise RuntimeError
+ raise RuntimeError
if cvar.Structure_StaticMemberString2 != "static member string 2":
- raise RuntimeError
+ raise RuntimeError
cvar.Structure_StaticMemberString2 = s
if cvar.Structure_StaticMemberString2 != s:
- raise RuntimeError
+ raise RuntimeError
if Structure.ConstStaticMemberString != "const static member string":
- raise RuntimeError
+ raise RuntimeError
if test_reference_input("hello") != "hello":
- raise RuntimeError
+ raise RuntimeError
s = test_reference_inout("hello")
if s != "hellohello":
- raise RuntimeError
+ raise RuntimeError
if test_reference_output() != "output":
- raise RuntimeError
+ raise RuntimeError
if stdstring_empty() != "":
- raise RuntimeError
+ raise RuntimeError
if c_empty() != "":
- raise RuntimeError
+ raise RuntimeError
if c_null() != None:
- raise RuntimeError
+ raise RuntimeError
if get_null(c_null()) != None:
- raise RuntimeError
+ raise RuntimeError
if get_null(c_empty()) != "non-null":
- raise RuntimeError
+ raise RuntimeError
if get_null(stdstring_empty()) != "non-null":
- raise RuntimeError
+ raise RuntimeError
diff --git a/Lib/python/pytypemaps.swg b/Lib/python/pytypemaps.swg
index 923c0e251..f4a6e4577 100644
--- a/Lib/python/pytypemaps.swg
+++ b/Lib/python/pytypemaps.swg
@@ -57,6 +57,9 @@
/* raise */
#define SWIG_Raise(obj, type, desc) SWIG_Python_Raise(obj, type, desc)
+/* clear errors */
+#define %error_clear PyErr_Clear()
+
/* Include the unified typemap library */
%include <typemaps/swigtypemaps.swg>
diff --git a/Lib/typemaps/std_strings.swg b/Lib/typemaps/std_strings.swg
index 842545826..28ef5e48d 100644
--- a/Lib/typemaps/std_strings.swg
+++ b/Lib/typemaps/std_strings.swg
@@ -17,12 +17,8 @@ SWIG_AsPtr_dec(String)(SWIG_Object obj, String **val)
return SWIG_OLDOBJ;
}
} else {
- static int init = 0;
- static swig_type_info* descriptor = 0;
- if (!init) {
- descriptor = SWIG_TypeQuery(#String " *");
- init = 1;
- }
+ %error_clear;
+ static swig_type_info *descriptor = SWIG_TypeQuery(#String " *");
if (descriptor) {
String *vptr;
int res = SWIG_ConvertPtr(obj, (void**)&vptr, descriptor, 0);
diff --git a/Lib/typemaps/swigtypemaps.swg b/Lib/typemaps/swigtypemaps.swg
index 3c3014f84..0c95c2f98 100644
--- a/Lib/typemaps/swigtypemaps.swg
+++ b/Lib/typemaps/swigtypemaps.swg
@@ -121,6 +121,12 @@
#endif
#endif
+/*==== clear errors ====*/
+
+#ifndef %error_clear
+#define %error_clear
+#endif
+
/*==== director output exception ====*/
#if defined(SWIG_DIRECTOR_TYPEMAPS)
--
2.47.0

View file

@ -68,7 +68,7 @@
Summary: Connects C/C++/Objective C to some high-level programming languages
Name: swig
Version: 4.2.1
Release: 8%{?dist}
Release: 9%{?dist}
License: GPL-3.0-or-later AND BSD-3-Clause
URL: https://www.swig.org/
Source0: http://downloads.sourceforge.net/project/swig/swig/swig-%{version}/swig-%{version}.tar.gz
@ -88,6 +88,10 @@ Patch2: swig-R-Fix-gcc-s-Wformat-security-warning-in-R-Raise-functi.patch
# Python 3.13 support: https://github.com/swig/swig/pull/2925
Patch3: swig-python-Python-3.13-strips-docstring-indent.patch
Patch4: swig-python-Python-3.13-deprecates-PyWeakref_GET_OBJECT.patch
# Fix seg fault passing invalid unicode values to std::string
# in upstream since 4.3.0
Patch5: swig-python-Add-li_std_string-runtime-test.patch
Patch6: swig-python-Fix-seg-fault-passing-invalid-unicode-values-to-std-.patch
BuildRequires: coreutils
BuildRequires: findutils
@ -371,6 +375,9 @@ install -pm 644 Tools/swig.gdb %{buildroot}%{_datadir}/%{name}/gdb
%{_datadir}/%{name}/gdb
%changelog
* Mon Dec 02 2024 Jitka Plesnikova <jplesnik@redhat.com> - 4.2.1-9
- Fix seg fault passing invalid unicode values to std::string (rhbz#2318762)
* Sat Jul 20 2024 Fedora Release Engineering <releng@fedoraproject.org> - 4.2.1-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild