Closed Osyotr closed 3 months ago
Yes, this is a bug.
The length calculation is wrong. The code uses wcslen()
to "calculate" the length of the converted string, however wcslen()
is just a strlen()
for wchar_t*
strings. So it returns the number of wide characters in a wchar_t*
string, but those do not need to be the same as the number of narrow characters (that is: char
) in the converted string. It just happens to be the same, if the wide character string only uses characters of the English alphabet where each wide character is converted to exactly one narrow character.
Instead of wcslen()
the code could use wcstombs()
's POSIX extension to calculate the length before doing the conversion.
POSIX specifies a common extension: if
dst
is a null pointer, this function returns the number of bytes that would be written todst
, if converted.
But that is an extension, so we should probably use wcsrtombs()
instead, where that behaviour is not an extension but part of the function and we do not need to rely on the presence of an extension.
Long story short: I'll try to prepare a fix.
Actual behavior
Writing images and views to files does not work because string conversion functions are not implemented properly: https://github.com/boostorg/gil/blob/eabd679f632be3170d98145fcc3b49e85df7cc4b/include/boost/gil/io/path_spec.hpp#L90-L97 The code above does not work for paths that contain non-ascii symbols. The string it produces does not have
\0
at the end.Expected behavior
Passing
std::filesystem::path
orstd::wstring
to io-related functions should work properly. Possible solution is to remove explicit string conversions, constructstd::filesystem::path
and use its.string()
method. Note that it may break on windows because of usage offopen
https://github.com/boostorg/gil/blob/eabd679f632be3170d98145fcc3b49e85df7cc4b/include/boost/gil/io/device.hpp#L105 (_wfopen
should be used on windows)C++ Minimal Working Example
I've extracted broken part (linked above) to reproduce the issue: https://godbolt.org/z/rvxsPG7a4
Environment