Fix seg fault handling template parameter expressions containing '<='

Recent commits ensure types are correctly stored in SwigType *. In
particular template parameters are enclosed within '<(' and ')>'.
Now we can confidently handle template parameters as really being
delimited as such to fix an infinite loop handling template expressions
containing '<' or '>'. The previous implementation only assumed
template parameters were delimited by '<' and '>'.

Issue #1037
This commit is contained in:
William S Fulton 2022-11-22 08:30:39 +00:00
commit 0341258af7
3 changed files with 24 additions and 5 deletions

View file

@ -7,6 +7,9 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
Version 4.2.0 (in progress) Version 4.2.0 (in progress)
=========================== ===========================
2022-11-22: wsfulton
#1037 Fix seg fault handling template parameter expressions containing '<='.
2022-11-18: wsfulton 2022-11-18: wsfulton
Duplicate class template instantiations via %template now issue a warning and are ignored. Duplicate class template instantiations via %template now issue a warning and are ignored.

View file

@ -37,3 +37,16 @@ void tester() {
// non-type template parameters working well in SWIG, below is a simple workaround as the 3rd parameter is defaulted for enable_if_t (which is just SFINAE to give a nice C++ compiler error) // non-type template parameters working well in SWIG, below is a simple workaround as the 3rd parameter is defaulted for enable_if_t (which is just SFINAE to give a nice C++ compiler error)
%template(enableif5) enableif5<int, int, true>; // workaround %template(enableif5) enableif5<int, int, true>; // workaround
%inline %{
// #1037 infinite loop
template <typename T, std::enable_if_t<sizeof(T) <= 4>>
void destId(T el) {}
/*
not yet fixed
template <typename T, std::enable_if_t<sizeof(T) >= 3>>
void destId(const T& el) {}
*/
%}

View file

@ -1234,17 +1234,20 @@ String *SwigType_prefix(const SwigType *t) {
while (d > c) { while (d > c) {
d--; d--;
if (*d == '>') { if (*d == '>' && (d > c) && *(d - 1) == ')') {
/* skip over template parameters */
int nest = 1; int nest = 1;
d--; d--;
d--;
while ((d > c) && (nest)) { while ((d > c) && (nest)) {
if (*d == '>') if (*d == '>' && *(d - 1) == ')')
nest++; nest++;
if (*d == '<') if (*d == '<' && *(d + 1) == '(')
nest--; nest--;
d--; d--;
} }
} }
if (*d == ')') { if (*d == ')') {
/* Skip over params */ /* Skip over params */
int nparen = 1; int nparen = 1;
@ -1259,10 +1262,10 @@ String *SwigType_prefix(const SwigType *t) {
} }
if (*d == '.') { if (*d == '.') {
char t = *(d + 1); char x = *(d + 1);
*(d + 1) = 0; *(d + 1) = 0;
r = NewString(c); r = NewString(c);
*(d + 1) = t; *(d + 1) = x;
return r; return r;
} }
} }