Don't accept strings too long to fit in char[N] with trailing NUL.

It was previously possible to assign "hello" to a variable backed by char[5]
storage in C, and the array contained the correct character data but without
the trailing NUL, which was unexpected in C.

This is not allowed any more, only "helo" can fit into a char[5] now and
anything else fails the type check, just as it already happened for the longer
strings before.

Closes #122
This commit is contained in:
Vadim Zeitlin 2013-12-23 20:47:43 +01:00 • committed by William S Fulton
commit cdf1ba9120
4 changed files with 13 additions and 7 deletions

View file

@ -10,8 +10,13 @@ Version 3.0.0 (in progress)
buffers in C code. buffers in C code.
This is a potential backwards compatibility break: a "char buf[5]" containing "ho\0la" was This is a potential backwards compatibility break: a "char buf[5]" containing "ho\0la" was
returned as a string of length 5 before, but is returned as a string of length 2 now. Apply returned as a string of length 5 before, but is returned as a string of length 2 now. Also,
"char FIXSIZE[ANY]" typemaps to explicitly choose the old behaviour. it was possible to assign a (non-NUL-terminated) string "hello" to such a buffer before but
now this fails and only "helo" can fit.
Apply "char FIXSIZE[ANY]" typemaps to explicitly choose the old behaviour.
*** POTENTIAL INCOMPATIBILITY ***
2013-12-23: talby 2013-12-23: talby
[Perl] Add support for directors. [Perl] Add support for directors.

View file

@ -170,9 +170,9 @@ is($primitive_types::def_namet, "hola", "namet");
$t->{var_namet} = $primitive_types::def_namet; $t->{var_namet} = $primitive_types::def_namet;
is($t->{var_namet}, $primitive_types::def_namet, "namet"); is($t->{var_namet}, $primitive_types::def_namet, "namet");
$t->{var_namet} = 'holac'; $t->{var_namet} = 'hola';
is($t->{var_namet}, 'holac', "namet"); is($t->{var_namet}, 'hola', "namet");
$t->{var_namet} = 'hol'; $t->{var_namet} = 'hol';

View file

@ -174,9 +174,9 @@ if t.var_namet != def_namet:
print "bad namet", t.var_namet, def_namet print "bad namet", t.var_namet, def_namet
raise RuntimeError raise RuntimeError
t.var_namet = 'holac' t.var_namet = 'hola'
if t.var_namet != 'holac': if t.var_namet != 'hola':
print "bad namet", t.var_namet print "bad namet", t.var_namet
raise RuntimeError raise RuntimeError

View file

@ -537,7 +537,8 @@ SWIG_As##CharName##Array(SWIG_Object obj, Char *val, size_t size)
Char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ; Char* cptr = 0; size_t csize = 0; int alloc = SWIG_OLDOBJ;
int res = SWIG_AsCharPtrAndSize(obj, &cptr, &csize, &alloc); int res = SWIG_AsCharPtrAndSize(obj, &cptr, &csize, &alloc);
if (SWIG_IsOK(res)) { if (SWIG_IsOK(res)) {
if ((csize == size + 1) && cptr && !(cptr[csize-1])) --csize; /* special case of single char conversion when we don't need space for NUL */
if (size == 1 && csize == 2 && cptr && !cptr[1]) --csize;
if (csize <= size) { if (csize <= size) {
if (val) { if (val) {
if (csize) memcpy(val, cptr, csize*sizeof(Char)); if (csize) memcpy(val, cptr, csize*sizeof(Char));