Skip to content

Commit 6158e45

Browse files
dschoGit for Windows Build Agent
authored andcommitted
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 <[email protected]>
1 parent b1b1ef2 commit 6158e45

File tree

1 file changed

+27
-0
lines changed

1 file changed

+27
-0
lines changed

git-compat-util.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,33 @@ extern char *gitdirname(char *);
281281

282282
#ifndef NO_ICONV
283283
#include <iconv.h>
284+
#ifdef _MSC_VER
285+
/*
286+
* At least version 1.14.0.11 of the libiconv NuPkg at
287+
* https://www.nuget.org/packages/libiconv/ does not set errno at all.
288+
*
289+
* Let's simulate it by testing whether we might have possibly run out of
290+
* space.
291+
*/
292+
static inline size_t msvc_iconv(iconv_t conv,
293+
const char **inpos, size_t *insize,
294+
char **outpos, size_t *outsize)
295+
{
296+
int saved_errno = errno;
297+
size_t res;
298+
299+
errno = ENOENT;
300+
res = iconv(conv, inpos, insize, outpos, outsize);
301+
if (!res)
302+
errno = saved_errno;
303+
else if (errno == ENOENT)
304+
errno = *outsize < 16 ? E2BIG : 0;
305+
306+
return res;
307+
}
308+
#undef iconv
309+
#define iconv msvc_iconv
310+
#endif
284311
#endif
285312

286313
#ifndef NO_OPENSSL

0 commit comments

Comments
 (0)