I've attached a patch (against CVS HEAD) which fixes the SWIG
std::string typemap to handle passing PHP strings containing zero bytes.
Without this patch, strings with embedded nuls are truncated when passed
to wrapped functions, which you can demonstrate with the attached
zerosafe.i - compile it with:
swig -c++ -php zerosafe.i
g++ -fPIC `php-config --includes` -Wall -O2 -g zerosafe_wrap.cpp -shared -o zerosafe.so
php -n -d extension_dir=. -r 'dl("zerosafe.so");zerosink("test\0it");'|cat -vet
without the patch applied, this displays:
And with the patch:
I've also changed the typemaps handling returned strings to use data()
rather than c_str() where we pass the length too. This is potentially
faster since the C++ standard allows a call to c_str() to result in a
I believe most contemporary std::string implementations don't actually
copy in this case - instead they either keep the string zero terminated
(e.g. GCC 4.0 does this) or leave space for a zero terminator to be
added on each call to c_str() (e.g. GCC 3.4 does this).
But even so, there's no reason at all to use c_str() instead of data()
in this case (and for completeness I've verified that returning
std::string does still work with this change).