msvc: work around iconv() not setting errno

When compiling with MSVC, we rely on NuPkgs to provide the binaries of
dependencies such as libiconv. The libiconv 1.14.0.11 package available
from https://www.nuget.org/packages/libiconv seems to have a bug where
it does not set errno (when we would expect it to be E2BIG).

Let's simulate the error condition by taking less than 16 bytes
remaining in the out buffer as an indicator that we ran out of space.
While 16 might seem a bit excessive (when converting from, say, any
encoding to UTF-8, 8 bytes should be fine), it is designed to be a safe
margin.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
This commit is contained in:
Johannes Schindelin
2016-10-21 02:46:59 -07:00
parent 13bd9a9246
commit 61dcdf41f2

View File

@@ -281,6 +281,33 @@ extern char *gitdirname(char *);
#ifndef NO_ICONV
#include <iconv.h>
#ifdef _MSC_VER
/*
* At least version 1.14.0.11 of the libiconv NuPkg at
* https://www.nuget.org/packages/libiconv/ does not set errno at all.
*
* Let's simulate it by testing whether we might have possibly run out of
* space.
*/
static inline size_t msvc_iconv(iconv_t conv,
const char **inpos, size_t *insize,
char **outpos, size_t *outsize)
{
int saved_errno = errno;
size_t res;
errno = ENOENT;
res = iconv(conv, inpos, insize, outpos, outsize);
if (!res)
errno = saved_errno;
else if (errno == ENOENT)
errno = *outsize < 16 ? E2BIG : 0;
return res;
}
#undef iconv
#define iconv msvc_iconv
#endif
#endif
#ifndef NO_OPENSSL