Bug#39762: iconv() with NULL inbuf gives strange results
Package: gconv-modules
Version: 2.1.1-12
Severity: normal
According to the libc info pages:
If INBUF is a null pointer the `iconv' function performs the
necessary action to put the state of the conversion into the
initial state.
But if inbuf is passed as a NULL pointer, then the values of outbuf
and outbytesleft get changed to especially unuseful values. For
example, given the program included below:
$ ./iconvnull l1 l1
< iconv_open("l1", "l1")
=> 0x805c7d0
< iconv(0x805c7d0, (nil), 0, 0x8049be0, 80)
> 0x805c7d0, (nil), 0, (nil), 134519856
=> 0
< iconv_close(0x805c7d0)
=> 0
Note that 0x8049be0 + 80 = 134519856. In this particular case, since
the transformation is the identity, I wouldn't expect *any* changes,
but the same results are obtained whatever the character sets, as far
as I can tell.
------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <iconv.h>
#define OUTLEN 80
int
main(int argc, char *argv[])
{
iconv_t cd;
const char *inbuf;
char *outbuf;
size_t inleft, outleft;
size_t numconv;
int status, save_err;
if (argc < 3) {
fprintf(stderr, "usage: iconvnull <to> <from>\n");
exit(EXIT_FAILURE);
}
if ((outbuf = malloc(OUTLEN)) == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
outleft = OUTLEN;
printf("< iconv_open(\"%s\", \"%s\")\n", argv[1], argv[2]);
cd = iconv_open(argv[1], argv[2]);
save_err = errno;
printf(" => %p\n", (void *) cd);
if (cd == (iconv_t) -1) {
printf("ERROR: %d (%s)\n", save_err, strerror(save_err));
exit(EXIT_FAILURE);
}
inbuf = NULL;
inleft = 0;
printf("< iconv(%p, %p, %ld, %p, %ld)\n",
(void *) cd, inbuf, (long) inleft, outbuf, (long) outleft);
numconv = iconv(cd, &inbuf, &inleft, &outbuf, &outleft);
save_err = errno;
printf("> %p, %p, %ld, %p, %ld\n",
(void *) cd, inbuf, (long) inleft, outbuf, (long) outleft);
printf(" => %ld\n", (long) numconv);
if (numconv == (size_t) -1) {
printf("ERROR: %d (%s)\n", save_err, strerror(save_err));
exit(EXIT_FAILURE);
}
printf("< iconv_close(%p)\n", (void *) cd);
status = iconv_close(cd);
save_err = errno;
printf(" => %d\n", status);
if (status == -1) {
printf("ERROR: %d (%s)\n", save_err, strerror(save_err));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
------------------------------------------------------------
-- System Information
Debian Release: potato
Architecture: i386
Kernel: Linux psyche 2.2.10 #1 Mon Jun 14 21:38:15 NZST 1999 i586
Versions of packages gconv-modules depends on:
ii libc6 2.1.1-12 GNU C Library: Shared libraries and timezone
Reply to: