Exemplo n.º 1
0
int
main (void)
{
    unsigned char buf[6] = { 0x25,  0xe2, 0x82, 0xac,  0xce, 0xbb };
    mbstate_t state;
    const char *src;
    wchar_t wc = 42;
    size_t n;
    int result = 0;
    const char *used_locale;

    setlocale (LC_CTYPE,"de_DE.UTF-8");
    /* Double check.  */
    used_locale = setlocale (LC_CTYPE, NULL);
    printf ("used locale: \"%s\"\n", used_locale);
    result = strcmp (used_locale, "de_DE.UTF-8");

    memset (&state, '\0', sizeof (state));

    src = (const char *) buf;
    show (mbsnrtowcs (&wc, &src, 1, 1, &state), 1, 37, buf + 1);
    show (mbsnrtowcs (&wc, &src, 3, 1, &state), 1, 8364, buf + 4);
    show (mbsnrtowcs (&wc, &src, 1, 1, &state), 0, 8364, buf + 5);
    show (mbsnrtowcs (&wc, &src, 1, 1, &state), 1, 955, buf + 6);

    return result;
}
Exemplo n.º 2
0
ATF_TC_BODY(mbsnrtowcs, tc)
{
	size_t i;
	const struct test *t;
	mbstate_t state;
	wchar_t buf[64];
	const char *src;
	size_t len;

	for (i = 0; i < __arraycount(tests); ++i) {
		t = &tests[i];
		ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C");
		ATF_REQUIRE(setlocale(LC_CTYPE, t->locale) != NULL);
		memset(&state, 0, sizeof(state));
		src = t->data;
		len = mbsnrtowcs(buf, &src, t->limit,
		    __arraycount(buf), &state);
		ATF_REQUIRE_EQ(src, t->data + t->limit);
		ATF_REQUIRE_EQ(len, t->output1_len);
		ATF_REQUIRE(wmemcmp(t->output1, buf, len) == 0);
		len = mbsnrtowcs(buf, &src, strlen(src) + 1,
		    __arraycount(buf), &state);
		ATF_REQUIRE_EQ(len, strlen(t->data) - t->limit);
		ATF_REQUIRE(wmemcmp(t->output2, buf, len + 1) == 0);
		ATF_REQUIRE_EQ(src, NULL);
	}
}
Exemplo n.º 3
0
static const char *mbsnr(const char *str, int inbuf, int outbuf)
{
	static char out[128];
	wchar_t tmp[128];
	int res;
	unsigned i;
	const char *s = str;
	mbstate_t ps;

	for (i = 0; i < 128; i++)
		tmp[i] = '~';

	memset(&ps, 0, sizeof(ps));
	res = mbsnrtowcs(tmp, &s, inbuf, outbuf, &ps);
	if (res < 0) {
		if (errno == EILSEQ) {
			snprintf(out, sizeof(out), "EILSEQ(%d)", (int)(s - str));
			return out;
		}
		return "unknown error";
	}
	if (tmp[res] == 0)
		tmp[res] = s ? 'z' : 'Z';

	for (i = 0; i < 128; i++) {
		out[i] = tmp[i];
		if (out[i] == '~') {
			out[i+1] = 0;
			break;
		}
	}
	return out;
}
size_t
mbsrtowcs(wchar_t *dst, const char **src, size_t len, mbstate_t *ps)
{
	static mbstate_t mbs;

	if (ps == NULL)
		ps = &mbs;
	return (mbsnrtowcs(dst, src, SIZE_MAX, len, ps));
}
Exemplo n.º 5
0
/* Print out utf-8 string. */
void pws(FILE *f, uint8_t *bp, size_t len)
{
    mbstate_t state;
    memset(&state, 0, sizeof(state));
    wchar_t *tmp;
    tmp = malloc((len + 1) * sizeof(wchar_t));
    size_t n;
    const char *ptr = (const char *)bp;
    n = mbsnrtowcs(tmp, &ptr, len, len, &state);
    tmp[n] = L'\0';
    fputws(tmp, stdout);
    free(tmp);
}
Exemplo n.º 6
0
static size_t
wmbsnrtowcs(wchar_t *dest, const char **src, size_t nbytes, size_t len)
{
    mbstate_t ps;
    size_t n;

    memset(&ps, 0, sizeof(mbstate_t));
    n = mbsnrtowcs(dest, src, nbytes, len, &ps);
    if (n!=(size_t)-1 && *src) {
        *src -= ps.__count;
    }

    return n;
}
Exemplo n.º 7
0
TEST(wchar, mbsnrtowcs) {
  wchar_t dst[128];
  const char* s = "hello, world!";
  const char* src;

  memset(dst, 0, sizeof(dst));
  src = s;
  ASSERT_EQ(0U, mbsnrtowcs(dst, &src, 0, 0, NULL));

  memset(dst, 0, sizeof(dst));
  src = s;
  ASSERT_EQ(2U, mbsnrtowcs(dst, &src, 2, 123, NULL)); // glibc chokes on SIZE_MAX here.
  ASSERT_EQ(L'h', dst[0]);
  ASSERT_EQ(L'e', dst[1]);
  ASSERT_EQ(&s[2], src);

  memset(dst, 0, sizeof(dst));
  src = s;
  ASSERT_EQ(3U, mbsnrtowcs(dst, &src, SIZE_MAX, 3, NULL));
  ASSERT_EQ(L'h', dst[0]);
  ASSERT_EQ(L'e', dst[1]);
  ASSERT_EQ(L'l', dst[2]);
  ASSERT_EQ(&s[3], src);
}
Exemplo n.º 8
0
static int
wmemstream_write(void *v, const char *b, int l)
{
	struct state	*st = v;
	wchar_t		*p;
	size_t		 nmc, len, end;

	end = (st->pos + l);

	if (end >= st->size) {
		/* 1.6 is (very) close to the golden ratio. */
		size_t	sz = st->size * 8 / 5;

		if (sz < end + 1)
			sz = end + 1;
		p = reallocarray(st->string, sz, sizeof(wchar_t));
		if (!p)
			return (-1);
		bzero(p + st->size, (sz - st->size) * sizeof(wchar_t));
		*st->pbuf = st->string = p;
		st->size = sz;
	}

	nmc = (st->size - st->pos) * sizeof(wchar_t);
	len = mbsnrtowcs(st->string + st->pos, &b, nmc, l, &st->mbs);
	if (len == (size_t)-1)
		return (-1);
	st->pos += len;

	if (st->pos > st->len) {
		st->len = st->pos;
		st->string[st->len] = L'\0';
	}

	*st->psize = st->pos;

	return (len);
}
Exemplo n.º 9
0
int
main (int argc, char *argv[])
{
  mbstate_t state;
  wchar_t wc;
  size_t ret;

  /* configure should already have checked that the locale is supported.  */
  if (setlocale (LC_ALL, "") == NULL)
    return 1;

  /* Test NUL byte input.  */
  {
    const char *src;

    memset (&state, '\0', sizeof (mbstate_t));

    src = "";
    ret = mbsnrtowcs (NULL, &src, 1, 0, &state);
    ASSERT (ret == 0);
    ASSERT (mbsinit (&state));

    src = "";
    ret = mbsnrtowcs (NULL, &src, 1, 1, &state);
    ASSERT (ret == 0);
    ASSERT (mbsinit (&state));

    wc = (wchar_t) 0xBADFACE;
    src = "";
    ret = mbsnrtowcs (&wc, &src, 1, 0, &state);
    ASSERT (ret == 0);
    ASSERT (wc == (wchar_t) 0xBADFACE);
    ASSERT (mbsinit (&state));

    wc = (wchar_t) 0xBADFACE;
    src = "";
    ret = mbsnrtowcs (&wc, &src, 1, 1, &state);
    ASSERT (ret == 0);
    ASSERT (wc == 0);
    ASSERT (mbsinit (&state));
  }

  if (argc > 1)
    {
      int unlimited;

      for (unlimited = 0; unlimited < 2; unlimited++)
        {
          #define BUFSIZE 10
          wchar_t buf[BUFSIZE];
          const char *src;
          mbstate_t temp_state;

          {
            size_t i;
            for (i = 0; i < BUFSIZE; i++)
              buf[i] = (wchar_t) 0xBADFACE;
          }

          switch (argv[1][0])
            {
            case '1':
              /* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
              {
                char input[] = "B\374\337er"; /* "Büßer" */
                memset (&state, '\0', sizeof (mbstate_t));

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input, 1, &state);
                ASSERT (ret == 1);
                ASSERT (wc == 'B');
                ASSERT (mbsinit (&state));
                input[0] = '\0';

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input + 1, 1, &state);
                ASSERT (ret == 1);
                ASSERT (wctob (wc) == (unsigned char) '\374');
                ASSERT (mbsinit (&state));
                input[1] = '\0';

                src = input + 2;
                temp_state = state;
                ret = mbsnrtowcs (NULL, &src, 4, unlimited ? BUFSIZE : 1, &temp_state);
                ASSERT (ret == 3);
                ASSERT (src == input + 2);
                ASSERT (mbsinit (&state));

                src = input + 2;
                ret = mbsnrtowcs (buf, &src, 4, unlimited ? BUFSIZE : 1, &state);
                ASSERT (ret == (unlimited ? 3 : 1));
                ASSERT (src == (unlimited ? NULL : input + 3));
                ASSERT (wctob (buf[0]) == (unsigned char) '\337');
                if (unlimited)
                  {
                    ASSERT (buf[1] == 'e');
                    ASSERT (buf[2] == 'r');
                    ASSERT (buf[3] == 0);
                    ASSERT (buf[4] == (wchar_t) 0xBADFACE);
                  }
                else
                  ASSERT (buf[1] == (wchar_t) 0xBADFACE);
                ASSERT (mbsinit (&state));
              }
              break;

            case '2':
              /* Locale encoding is UTF-8.  */
              {
                char input[] = "B\303\274\303\237er"; /* "Büßer" */
                memset (&state, '\0', sizeof (mbstate_t));

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input, 1, &state);
                ASSERT (ret == 1);
                ASSERT (wc == 'B');
                ASSERT (mbsinit (&state));
                input[0] = '\0';

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input + 1, 1, &state);
                ASSERT (ret == (size_t)(-2));
                ASSERT (wc == (wchar_t) 0xBADFACE);
                ASSERT (!mbsinit (&state));
                input[1] = '\0';

                src = input + 2;
                temp_state = state;
                ret = mbsnrtowcs (NULL, &src, 6, unlimited ? BUFSIZE : 2, &temp_state);
                ASSERT (ret == 4);
                ASSERT (src == input + 2);
                ASSERT (!mbsinit (&state));

                src = input + 2;
                ret = mbsnrtowcs (buf, &src, 6, unlimited ? BUFSIZE : 2, &state);
                ASSERT (ret == (unlimited ? 4 : 2));
                ASSERT (src == (unlimited ? NULL : input + 5));
                ASSERT (wctob (buf[0]) == EOF);
                ASSERT (wctob (buf[1]) == EOF);
                if (unlimited)
                  {
                    ASSERT (buf[2] == 'e');
                    ASSERT (buf[3] == 'r');
                    ASSERT (buf[4] == 0);
                    ASSERT (buf[5] == (wchar_t) 0xBADFACE);
                  }
                else
                  ASSERT (buf[2] == (wchar_t) 0xBADFACE);
                ASSERT (mbsinit (&state));
              }
              break;

            case '3':
              /* Locale encoding is EUC-JP.  */
              {
                char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
                memset (&state, '\0', sizeof (mbstate_t));

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input, 1, &state);
                ASSERT (ret == 1);
                ASSERT (wc == '<');
                ASSERT (mbsinit (&state));
                input[0] = '\0';

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input + 1, 2, &state);
                ASSERT (ret == 2);
                ASSERT (wctob (wc) == EOF);
                ASSERT (mbsinit (&state));
                input[1] = '\0';
                input[2] = '\0';

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input + 3, 1, &state);
                ASSERT (ret == (size_t)(-2));
                ASSERT (wc == (wchar_t) 0xBADFACE);
                ASSERT (!mbsinit (&state));
                input[3] = '\0';

                src = input + 4;
                temp_state = state;
                ret = mbsnrtowcs (NULL, &src, 5, unlimited ? BUFSIZE : 2, &temp_state);
                ASSERT (ret == 3);
                ASSERT (src == input + 4);
                ASSERT (!mbsinit (&state));

                src = input + 4;
                ret = mbsnrtowcs (buf, &src, 5, unlimited ? BUFSIZE : 2, &state);
                ASSERT (ret == (unlimited ? 3 : 2));
                ASSERT (src == (unlimited ? NULL : input + 7));
                ASSERT (wctob (buf[0]) == EOF);
                ASSERT (wctob (buf[1]) == EOF);
                if (unlimited)
                  {
                    ASSERT (buf[2] == '>');
                    ASSERT (buf[3] == 0);
                    ASSERT (buf[4] == (wchar_t) 0xBADFACE);
                  }
                else
                  ASSERT (buf[2] == (wchar_t) 0xBADFACE);
                ASSERT (mbsinit (&state));
              }
              break;

            case '4':
              /* Locale encoding is GB18030.  */
              {
                char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
                memset (&state, '\0', sizeof (mbstate_t));

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input, 1, &state);
                ASSERT (ret == 1);
                ASSERT (wc == 'B');
                ASSERT (mbsinit (&state));
                input[0] = '\0';

                wc = (wchar_t) 0xBADFACE;
                ret = mbrtowc (&wc, input + 1, 1, &state);
                ASSERT (ret == (size_t)(-2));
                ASSERT (wc == (wchar_t) 0xBADFACE);
                ASSERT (!mbsinit (&state));
                input[1] = '\0';

                src = input + 2;
                temp_state = state;
                ret = mbsnrtowcs (NULL, &src, 8, unlimited ? BUFSIZE : 2, &temp_state);
                ASSERT (ret == 4);
                ASSERT (src == input + 2);
                ASSERT (!mbsinit (&state));

                src = input + 2;
                ret = mbsnrtowcs (buf, &src, 8, unlimited ? BUFSIZE : 2, &state);
                ASSERT (ret == (unlimited ? 4 : 2));
                ASSERT (src == (unlimited ? NULL : input + 7));
                ASSERT (wctob (buf[0]) == EOF);
                ASSERT (wctob (buf[1]) == EOF);
                if (unlimited)
                  {
                    ASSERT (buf[2] == 'e');
                    ASSERT (buf[3] == 'r');
                    ASSERT (buf[4] == 0);
                    ASSERT (buf[5] == (wchar_t) 0xBADFACE);
                  }
                else
                  ASSERT (buf[2] == (wchar_t) 0xBADFACE);
                ASSERT (mbsinit (&state));
              }
              break;

            default:
              return 1;
            }
        }

      return 0;
    }

  return 1;
}
Exemplo n.º 10
0
int
main(int argc, char *argv[])
{
	mbstate_t state;
	wchar_t wc;
	size_t ret;
	int mode;

	/* configure should already have checked that the locale is supported.  */
	if (setlocale(LC_ALL, "") == NULL) {
		fprintf(stderr, "unable to set standard locale\n");
		return 1;
	}

	/* Test NUL byte input.  */
	{
		const char *src;

		memset(&state, '\0', sizeof(mbstate_t));

		src = "";
		ret = mbsnrtowcs(NULL, &src, 1, 0, &state);
		assert(ret == 0);
		assert(mbsinit (&state));

		src = "";
		ret = mbsnrtowcs(NULL, &src, 1, 1, &state);
		assert(ret == 0);
		assert(mbsinit (&state));

		wc = (wchar_t) 0xBADFACE;
		src = "";
		ret = mbsnrtowcs(&wc, &src, 1, 0, &state);
		assert(ret == 0);
		assert(wc == (wchar_t) 0xBADFACE);
		assert(mbsinit (&state));

		wc = (wchar_t) 0xBADFACE;
		src = "";
		ret = mbsnrtowcs(&wc, &src, 1, 1, &state);
		assert(ret == 0);
		assert(wc == 0);
		assert(mbsinit (&state));
	}

	for (mode = '1'; mode <= '4'; ++mode) {
		int unlimited;
		for (unlimited = 0; unlimited < 2; unlimited++) {
			wchar_t buf[BUFSIZE];
			const char *src;
			mbstate_t temp_state;

			{
				size_t i;
				for (i = 0; i < BUFSIZE; i++)
					buf[i] = (wchar_t) 0xBADFACE;
			}

			switch (mode) {
				case '1':
					/* Locale encoding is ISO-8859-1 or ISO-8859-15.  */
		    	printf("ISO8859-1 ...\n");
				{
					char input[] = "B\374\337er"; /* "Büßer" */
					memset(&state, '\0', sizeof(mbstate_t));

					if (setlocale (LC_ALL, "en_US.ISO8859-1") == NULL) {
						fprintf(stderr,
							"unable to set ISO8859-1 locale, skipping\n");
						break;
					}

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input, 1, &state);
					assert(ret == 1);
					assert(wc == 'B');
					assert(mbsinit (&state));
					input[0] = '\0';

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input + 1, 1, &state);
					assert(ret == 1);
					assert(wctob (wc) == (unsigned char) '\374');
					assert(mbsinit (&state));
					input[1] = '\0';

					src = input + 2;
					temp_state = state;
					ret = mbsnrtowcs(NULL, &src, 4, unlimited ? BUFSIZE : 1,
						&temp_state);
					assert(ret == 3);
					assert(src == input + 2);
					assert(mbsinit (&state));

					src = input + 2;
					ret = mbsnrtowcs(buf, &src, 4, unlimited ? BUFSIZE : 1,
						&state);
					assert(ret == (unlimited ? 3 : 1));
					assert(src == (unlimited ? NULL : input + 3));
					assert(wctob (buf[0]) == (unsigned char) '\337');
					if (unlimited) {
						assert(buf[1] == 'e');
						assert(buf[2] == 'r');
						assert(buf[3] == 0);
						assert(buf[4] == (wchar_t) 0xBADFACE);
					} else
						assert(buf[1] == (wchar_t) 0xBADFACE);
					assert(mbsinit (&state));
				}
					break;

				case '2':
					/* Locale encoding is UTF-8.  */
		    	printf("UTF-8 ...\n");
				{
					char input[] = "B\303\274\303\237er"; /* "Büßer" */
					memset(&state, '\0', sizeof(mbstate_t));

					if (setlocale (LC_ALL, "en_US.UTF-8") == NULL) {
						fprintf(stderr,
							"unable to set UTF-8 locale, skipping\n");
						break;
					}

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input, 1, &state);
					assert(ret == 1);
					assert(wc == 'B');
					assert(mbsinit (&state));
					input[0] = '\0';

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input + 1, 1, &state);
					assert(ret == (size_t)(-2));
					assert(wc == (wchar_t) 0xBADFACE);
					assert(!mbsinit (&state));
					input[1] = '\0';

// Copying mbstate_t doesn't really copy the ICU-converter's state, so this
// doesn't work on Haiku.
#ifndef __HAIKU__
					src = input + 2;
					temp_state = state;
					ret = mbsnrtowcs(NULL, &src, 6, unlimited ? BUFSIZE : 2,
						&temp_state);
					assert(ret == 4);
					assert(src == input + 2);
					assert(!mbsinit (&state));
#endif

					src = input + 2;
					ret = mbsnrtowcs(buf, &src, 6, unlimited ? BUFSIZE : 2,
						&state);
					assert(ret == (unlimited ? 4 : 2));
					assert(src == (unlimited ? NULL : input + 5));
					assert(wctob (buf[0]) == EOF);
					assert(wctob (buf[1]) == EOF);
					if (unlimited) {
						assert(buf[2] == 'e');
						assert(buf[3] == 'r');
						assert(buf[4] == 0);
						assert(buf[5] == (wchar_t) 0xBADFACE);
					} else
						assert(buf[2] == (wchar_t) 0xBADFACE);
					assert(mbsinit (&state));
				}
					break;

				case '3':
					/* Locale encoding is EUC-JP.  */
		    	printf("EUC-JP ...\n");
				{
					char input[] = "<\306\374\313\334\270\354>"; /* "<日本語>" */
					memset(&state, '\0', sizeof(mbstate_t));

					if (setlocale (LC_ALL, "en_US.EUC-JP") == NULL) {
						fprintf(stderr,
							"unable to set EUC-JP locale, skipping\n");
						break;
					}

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input, 1, &state);
					assert(ret == 1);
					assert(wc == '<');
					assert(mbsinit (&state));
					input[0] = '\0';

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input + 1, 2, &state);
					assert(ret == 2);
					assert(wctob (wc) == EOF);
					assert(mbsinit (&state));
					input[1] = '\0';
					input[2] = '\0';

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input + 3, 1, &state);
					assert(ret == (size_t)(-2));
					assert(wc == (wchar_t) 0xBADFACE);
					assert(!mbsinit (&state));
					input[3] = '\0';

// Copying mbstate_t doesn't really copy the ICU-converter's state, so this
// doesn't work on Haiku.
#ifndef __HAIKU__
					src = input + 4;
					temp_state = state;
					ret = mbsnrtowcs(NULL, &src, 5, unlimited ? BUFSIZE : 2,
						&temp_state);
					assert(ret == 3);
					assert(src == input + 4);
					assert(!mbsinit (&state));
#endif

					src = input + 4;
					ret = mbsnrtowcs(buf, &src, 5, unlimited ? BUFSIZE : 2,
						&state);
					assert(ret == (unlimited ? 3 : 2));
					assert(src == (unlimited ? NULL : input + 7));
					assert(wctob (buf[0]) == EOF);
					assert(wctob (buf[1]) == EOF);
					if (unlimited) {
						assert(buf[2] == '>');
						assert(buf[3] == 0);
						assert(buf[4] == (wchar_t) 0xBADFACE);
					} else
						assert(buf[2] == (wchar_t) 0xBADFACE);
					assert(mbsinit (&state));
				}
					break;

				case '4':
					/* Locale encoding is GB18030.  */
		    	printf("GB18030 ...\n");
				{
					char input[] = "B\250\271\201\060\211\070er"; /* "Büßer" */
					memset(&state, '\0', sizeof(mbstate_t));

					if (setlocale (LC_ALL, "en_US.GB18030") == NULL) {
						fprintf(stderr,
							"unable to set GB18030 locale, skipping\n");
						break;
					}

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input, 1, &state);
					assert(ret == 1);
					assert(wc == 'B');
					assert(mbsinit (&state));
					input[0] = '\0';

					wc = (wchar_t) 0xBADFACE;
					ret = mbrtowc(&wc, input + 1, 1, &state);
					assert(ret == (size_t)(-2));
					assert(wc == (wchar_t) 0xBADFACE);
					assert(!mbsinit (&state));
					input[1] = '\0';

// Copying mbstate_t doesn't really copy the ICU-converter's state, so this
// doesn't work on Haiku.
#ifndef __HAIKU__
					src = input + 2;
					temp_state = state;
					ret = mbsnrtowcs(NULL, &src, 8, unlimited ? BUFSIZE : 2,
						&temp_state);
					assert(ret == 4);
					assert(src == input + 2);
					assert(!mbsinit (&state));
#endif

					src = input + 2;
					ret = mbsnrtowcs(buf, &src, 8, unlimited ? BUFSIZE : 2,
						&state);
					assert(ret == (unlimited ? 4 : 2));
					assert(src == (unlimited ? NULL : input + 7));
					assert(wctob (buf[0]) == EOF);
					assert(wctob (buf[1]) == EOF);
					if (unlimited) {
						assert(buf[2] == 'e');
						assert(buf[3] == 'r');
						assert(buf[4] == 0);
						assert(buf[5] == (wchar_t) 0xBADFACE);
					} else
						assert(buf[2] == (wchar_t) 0xBADFACE);
					assert(mbsinit (&state));
				}
					break;

				default:
					return 1;
			}
		}
	}

	return 0;
}
Exemplo n.º 11
0
size_t mbsrtowcs(wchar_t* dst, const char** src, size_t len, mbstate_t* ps) {
  return mbsnrtowcs(dst, src, SIZE_MAX, len, ps);
}
Exemplo n.º 12
0
//! helper that translates an utf8 string to ascii with some error return codes
char * utf8toascii(const char *str_src, longlong *len_src,
    struct workspace_t * ws, char *str_dst, int limit) {

    mbstate_t *mbstate = ws->mbstate;
    size_t len_mbsnrtowcs, len_ret = LENGTH_MAX, len_min = LENGTH_MAX;
    char *ret = str_dst, *in_s = (char *)str_src; //utf8;

    memset((void *)mbstate, '\0', sizeof(mbstate_t));
    if ( (len_mbsnrtowcs = mbsnrtowcs(NULL, &str_src, *len_src, 0, mbstate)) == (size_t) -1 ) {
        debug_print("str_src(%s): %s", str_src, strerror(errno));
        return NULL;
    }

    len_min = MIN(len_mbsnrtowcs, limit);

    debug_print("1] len_mbsnrtowcs(%zu) limit(%d) LENGTH_MAX(%d) min(%zu)",
        len_mbsnrtowcs,
        limit,
        LENGTH_MAX,
        len_min);

    if ( len_mbsnrtowcs == *len_src ) {
        strncpy(str_dst, str_src, len_min);
        str_dst[len_min] = '\0';
        str_dst[len_min + 1] = '\0'; // NULLNULL is proper string ending when parsing utf8
        *len_src = len_min;
        return str_dst;
    }

    if ( ws->iconv_init == 0 ) {
        if ( (ws->ic = iconv_open("ascii//TRANSLIT", "UTF-8")) == (iconv_t) -1 ) {
            debug_print("%s", "failed to initialize iconv");
            return NULL;
        }
        ws->iconv_init = 1;
    }

    if ( iconv(ws->ic, &in_s, (size_t *) len_src, &ret, &len_ret) == (size_t) -1 ) {
        debug_print("in_s(%s) len_src(%lld) len_ret(%zu) error: %s",
            str_src,
            *len_src,
            len_ret,
            strerror(errno));
        if ( errno == E2BIG ) {
            debug_print("inside E2BIG len_mbsnrtowcs(%zu) len_src(%lld)",
                len_mbsnrtowcs,
                *len_src);
            len_mbsnrtowcs = len_min; //LENGTH_MAX;
        } else {
            return NULL;
        }
    }

    *len_src = len_min; // adjust converted length
    str_dst[len_min] = '\0';
    str_dst[len_min + 1] = '\0'; // NULLNULL is proper string ending when parsing utf8

    // iconv house cleaning as per man 3 iconv_open
    if ( iconv(ws->ic, NULL, NULL, NULL, NULL) == (size_t) -1 ) {
        return NULL;
    }

    return str_dst;
}
Exemplo n.º 13
0
static int
do_test (void)
{
  struct sigaction sa;
  sa.sa_handler = handler;
  sa.sa_flags = 0;
  sigemptyset (&sa.sa_mask);

  sigaction (SIGABRT, &sa, NULL);

  /* Avoid all the buffer overflow messages on stderr.  */
  int fd = open (_PATH_DEVNULL, O_WRONLY);
  if (fd == -1)
    close (STDERR_FILENO);
  else
    {
      dup2 (fd, STDERR_FILENO);
      close (fd);
    }
  setenv ("LIBC_FATAL_STDERR_", "1", 1);

  struct A { char buf1[9]; char buf2[1]; } a;
  struct wA { wchar_t buf1[9]; wchar_t buf2[1]; } wa;

  printf ("Test checking routines at fortify level %d\n",
#ifdef __USE_FORTIFY_LEVEL
	  (int) __USE_FORTIFY_LEVEL
#else
	  0
#endif
	  );

  /* These ops can be done without runtime checking of object size.  */
  memcpy (buf, "abcdefghij", 10);
  memmove (buf + 1, buf, 9);
  if (memcmp (buf, "aabcdefghi", 10))
    FAIL ();

  if (mempcpy (buf + 5, "abcde", 5) != buf + 10
      || memcmp (buf, "aabcdabcde", 10))
    FAIL ();

  memset (buf + 8, 'j', 2);
  if (memcmp (buf, "aabcdabcjj", 10))
    FAIL ();

  strcpy (buf + 4, "EDCBA");
  if (memcmp (buf, "aabcEDCBA", 10))
    FAIL ();

  if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
    FAIL ();

  strncpy (buf + 6, "X", 4);
  if (memcmp (buf, "aabcEDX\0\0", 10))
    FAIL ();

  if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10))
    FAIL ();

  if (snprintf (buf + 7, 3, "%s", "987654") != 6
      || memcmp (buf, "aabcEDX98", 10))
    FAIL ();

  /* These ops need runtime checking, but shouldn't __chk_fail.  */
  memcpy (buf, "abcdefghij", l0 + 10);
  memmove (buf + 1, buf, l0 + 9);
  if (memcmp (buf, "aabcdefghi", 10))
    FAIL ();

  if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
      || memcmp (buf, "aabcdabcde", 10))
    FAIL ();

  memset (buf + 8, 'j', l0 + 2);
  if (memcmp (buf, "aabcdabcjj", 10))
    FAIL ();

  strcpy (buf + 4, str1 + 5);
  if (memcmp (buf, "aabcEDCBA", 10))
    FAIL ();

  if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
    FAIL ();

  strncpy (buf + 6, "X", l0 + 4);
  if (memcmp (buf, "aabcEDX\0\0", 10))
    FAIL ();

  if (stpncpy (buf + 5, "cd", l0 + 5) != buf + 7
      || memcmp (buf, "aabcEcd\0\0", 10))
    FAIL ();

  if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEcd67", 10))
    FAIL ();

  if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEcd98", 10))
    FAIL ();

  buf[l0 + 8] = '\0';
  strcat (buf, "A");
  if (memcmp (buf, "aabcEcd9A", 10))
    FAIL ();

  buf[l0 + 7] = '\0';
  strncat (buf, "ZYXWV", l0 + 2);
  if (memcmp (buf, "aabcEcdZY", 10))
    FAIL ();

  memcpy (a.buf1, "abcdefghij", l0 + 10);
  memmove (a.buf1 + 1, a.buf1, l0 + 9);
  if (memcmp (a.buf1, "aabcdefghi", 10))
    FAIL ();

  if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
      || memcmp (a.buf1, "aabcdabcde", 10))
    FAIL ();

  memset (a.buf1 + 8, 'j', l0 + 2);
  if (memcmp (a.buf1, "aabcdabcjj", 10))
    FAIL ();

#if __USE_FORTIFY_LEVEL < 2
  /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
     and sufficient GCC support, as the string operations overflow
     from a.buf1 into a.buf2.  */
  strcpy (a.buf1 + 4, str1 + 5);
  if (memcmp (a.buf1, "aabcEDCBA", 10))
    FAIL ();

  if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9
      || memcmp (a.buf1, "aabcEDCBF", 10))
    FAIL ();

  strncpy (a.buf1 + 6, "X", l0 + 4);
  if (memcmp (a.buf1, "aabcEDX\0\0", 10))
    FAIL ();

  if (sprintf (a.buf1 + 7, "%d", num1) != 2
      || memcmp (a.buf1, "aabcEDX67", 10))
    FAIL ();

  if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
      || memcmp (a.buf1, "aabcEDX98", 10))
    FAIL ();

  a.buf1[l0 + 8] = '\0';
  strcat (a.buf1, "A");
  if (memcmp (a.buf1, "aabcEDX9A", 10))
    FAIL ();

  a.buf1[l0 + 7] = '\0';
  strncat (a.buf1, "ZYXWV", l0 + 2);
  if (memcmp (a.buf1, "aabcEDXZY", 10))
    FAIL ();

#endif

#if __USE_FORTIFY_LEVEL >= 1
  /* Now check if all buffer overflows are caught at runtime.  */

  CHK_FAIL_START
  memcpy (buf + 1, "abcdefghij", l0 + 10);
  CHK_FAIL_END

  CHK_FAIL_START
  memmove (buf + 2, buf + 1, l0 + 9);
  CHK_FAIL_END

  CHK_FAIL_START
  p = mempcpy (buf + 6, "abcde", l0 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  memset (buf + 9, 'j', l0 + 2);
  CHK_FAIL_END

  CHK_FAIL_START
  strcpy (buf + 5, str1 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  p = stpcpy (buf + 9, str2);
  CHK_FAIL_END

  CHK_FAIL_START
  strncpy (buf + 7, "X", l0 + 4);
  CHK_FAIL_END

  CHK_FAIL_START
  stpncpy (buf + 6, "cd", l0 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  sprintf (buf + 8, "%d", num1);
  CHK_FAIL_END

  CHK_FAIL_START
  snprintf (buf + 8, l0 + 3, "%d", num2);
  CHK_FAIL_END

  memcpy (buf, str1 + 2, l0 + 9);
  CHK_FAIL_START
  strcat (buf, "AB");
  CHK_FAIL_END

  memcpy (buf, str1 + 3, l0 + 8);
  CHK_FAIL_START
  strncat (buf, "ZYXWV", l0 + 3);
  CHK_FAIL_END

  CHK_FAIL_START
  memcpy (a.buf1 + 1, "abcdefghij", l0 + 10);
  CHK_FAIL_END

  CHK_FAIL_START
  memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9);
  CHK_FAIL_END

  CHK_FAIL_START
  p = mempcpy (a.buf1 + 6, "abcde", l0 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  memset (a.buf1 + 9, 'j', l0 + 2);
  CHK_FAIL_END

#if __USE_FORTIFY_LEVEL >= 2
# define O 0
#else
# define O 1
#endif

  CHK_FAIL_START
  strcpy (a.buf1 + (O + 4), str1 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  p = stpcpy (a.buf1 + (O + 8), str2);
  CHK_FAIL_END

  CHK_FAIL_START
  strncpy (a.buf1 + (O + 6), "X", l0 + 4);
  CHK_FAIL_END

  CHK_FAIL_START
  sprintf (a.buf1 + (O + 7), "%d", num1);
  CHK_FAIL_END

  CHK_FAIL_START
  snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
  CHK_FAIL_END

  memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O);
  CHK_FAIL_START
  strcat (a.buf1, "AB");
  CHK_FAIL_END

  memcpy (a.buf1, str1 + (4 - O), l0 + 7 + O);
  CHK_FAIL_START
  strncat (a.buf1, "ZYXWV", l0 + 3);
  CHK_FAIL_END
#endif


  /* These ops can be done without runtime checking of object size.  */
  wmemcpy (wbuf, L"abcdefghij", 10);
  wmemmove (wbuf + 1, wbuf, 9);
  if (wmemcmp (wbuf, L"aabcdefghi", 10))
    FAIL ();

  if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
      || wmemcmp (wbuf, L"aabcdabcde", 10))
    FAIL ();

  wmemset (wbuf + 8, L'j', 2);
  if (wmemcmp (wbuf, L"aabcdabcjj", 10))
    FAIL ();

  wcscpy (wbuf + 4, L"EDCBA");
  if (wmemcmp (wbuf, L"aabcEDCBA", 10))
    FAIL ();

  if (wcpcpy (wbuf + 8, L"F") != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
    FAIL ();

  wcsncpy (wbuf + 6, L"X", 4);
  if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
    FAIL ();

  if (swprintf (wbuf + 7, 3, L"%ls", L"987654") >= 0
      || wmemcmp (wbuf, L"aabcEDX98", 10))
    FAIL ();

  if (swprintf (wbuf + 7, 3, L"64") != 2
      || wmemcmp (wbuf, L"aabcEDX64", 10))
    FAIL ();

  /* These ops need runtime checking, but shouldn't __chk_fail.  */
  wmemcpy (wbuf, L"abcdefghij", l0 + 10);
  wmemmove (wbuf + 1, wbuf, l0 + 9);
  if (wmemcmp (wbuf, L"aabcdefghi", 10))
    FAIL ();

  if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
      || wmemcmp (wbuf, L"aabcdabcde", 10))
    FAIL ();

  wmemset (wbuf + 8, L'j', l0 + 2);
  if (wmemcmp (wbuf, L"aabcdabcjj", 10))
    FAIL ();

  wcscpy (wbuf + 4, wstr1 + 5);
  if (wmemcmp (wbuf, L"aabcEDCBA", 10))
    FAIL ();

  if (wcpcpy (wbuf + 8, wstr2) != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
    FAIL ();

  wcsncpy (wbuf + 6, L"X", l0 + 4);
  if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
    FAIL ();

  if (wcpncpy (wbuf + 5, L"cd", l0 + 5) != wbuf + 7
      || wmemcmp (wbuf, L"aabcEcd\0\0", 10))
    FAIL ();

  if (swprintf (wbuf + 7, 3, L"%d", num2) >= 0
      || wmemcmp (wbuf, L"aabcEcd98", 10))
    FAIL ();

  wbuf[l0 + 8] = L'\0';
  wcscat (wbuf, L"A");
  if (wmemcmp (wbuf, L"aabcEcd9A", 10))
    FAIL ();

  wbuf[l0 + 7] = L'\0';
  wcsncat (wbuf, L"ZYXWV", l0 + 2);
  if (wmemcmp (wbuf, L"aabcEcdZY", 10))
    FAIL ();

  wmemcpy (wa.buf1, L"abcdefghij", l0 + 10);
  wmemmove (wa.buf1 + 1, wa.buf1, l0 + 9);
  if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
    FAIL ();

  if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
      || wmemcmp (wa.buf1, L"aabcdabcde", 10))
    FAIL ();

  wmemset (wa.buf1 + 8, L'j', l0 + 2);
  if (wmemcmp (wa.buf1, L"aabcdabcjj", 10))
    FAIL ();

#if __USE_FORTIFY_LEVEL < 2
  /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
     and sufficient GCC support, as the string operations overflow
     from a.buf1 into a.buf2.  */
  wcscpy (wa.buf1 + 4, wstr1 + 5);
  if (wmemcmp (wa.buf1, L"aabcEDCBA", 10))
    FAIL ();

  if (wcpcpy (wa.buf1 + 8, wstr2) != wa.buf1 + 9
      || wmemcmp (wa.buf1, L"aabcEDCBF", 10))
    FAIL ();

  wcsncpy (wa.buf1 + 6, L"X", l0 + 4);
  if (wmemcmp (wa.buf1, L"aabcEDX\0\0", 10))
    FAIL ();

  if (swprintf (wa.buf1 + 7, 3, L"%d", num2) >= 0
      || wmemcmp (wa.buf1, L"aabcEDX98", 10))
    FAIL ();

  wa.buf1[l0 + 8] = L'\0';
  wcscat (wa.buf1, L"A");
  if (wmemcmp (wa.buf1, L"aabcEDX9A", 10))
    FAIL ();

  wa.buf1[l0 + 7] = L'\0';
  wcsncat (wa.buf1, L"ZYXWV", l0 + 2);
  if (wmemcmp (wa.buf1, L"aabcEDXZY", 10))
    FAIL ();

#endif

#if __USE_FORTIFY_LEVEL >= 1
  /* Now check if all buffer overflows are caught at runtime.  */

  CHK_FAIL_START
  wmemcpy (wbuf + 1, L"abcdefghij", l0 + 10);
  CHK_FAIL_END

  CHK_FAIL_START
  wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
  CHK_FAIL_END

  CHK_FAIL_START
    wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  wmemset (wbuf + 9, L'j', l0 + 2);
  CHK_FAIL_END

  CHK_FAIL_START
  wcscpy (wbuf + 5, wstr1 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  wp = wcpcpy (wbuf + 9, wstr2);
  CHK_FAIL_END

  CHK_FAIL_START
  wcsncpy (wbuf + 7, L"X", l0 + 4);
  CHK_FAIL_END

  CHK_FAIL_START
  wcpncpy (wbuf + 6, L"cd", l0 + 5);
  CHK_FAIL_END

  wmemcpy (wbuf, wstr1 + 2, l0 + 9);
  CHK_FAIL_START
  wcscat (wbuf, L"AB");
  CHK_FAIL_END

  wmemcpy (wbuf, wstr1 + 3, l0 + 8);
  CHK_FAIL_START
  wcsncat (wbuf, L"ZYXWV", l0 + 3);
  CHK_FAIL_END

  CHK_FAIL_START
  wmemcpy (wa.buf1 + 1, L"abcdefghij", l0 + 10);
  CHK_FAIL_END

  CHK_FAIL_START
  wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
  CHK_FAIL_END

  CHK_FAIL_START
  wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  wmemset (wa.buf1 + 9, L'j', l0 + 2);
  CHK_FAIL_END

#if __USE_FORTIFY_LEVEL >= 2
# define O 0
#else
# define O 1
#endif

  CHK_FAIL_START
  wcscpy (wa.buf1 + (O + 4), wstr1 + 5);
  CHK_FAIL_END

  CHK_FAIL_START
  wp = wcpcpy (wa.buf1 + (O + 8), wstr2);
  CHK_FAIL_END

  CHK_FAIL_START
  wcsncpy (wa.buf1 + (O + 6), L"X", l0 + 4);
  CHK_FAIL_END

  wmemcpy (wa.buf1, wstr1 + (3 - O), l0 + 8 + O);
  CHK_FAIL_START
  wcscat (wa.buf1, L"AB");
  CHK_FAIL_END

  wmemcpy (wa.buf1, wstr1 + (4 - O), l0 + 7 + O);
  CHK_FAIL_START
  wcsncat (wa.buf1, L"ZYXWV", l0 + 3);
  CHK_FAIL_END
#endif


  /* Now checks for %n protection.  */

  /* Constant literals passed directly are always ok
     (even with warnings about possible bugs from GCC).  */
  int n1, n2;
  if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2
      || n1 != 1 || n2 != 2)
    FAIL ();

  /* In this case the format string is not known at compile time,
     but resides in read-only memory, so is ok.  */
  if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2
      || n1 != 1 || n2 != 2)
    FAIL ();

  strcpy (buf2 + 2, "%n%s%n");
  /* When the format string is writable and contains %n,
     with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
  CHK_FAIL2_START
  if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2)
    FAIL ();
  CHK_FAIL2_END

  CHK_FAIL2_START
  if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2)
    FAIL ();
  CHK_FAIL2_END

  /* But if there is no %n, even writable format string
     should work.  */
  buf2[6] = '\0';
  if (sprintf (buf, buf2 + 4, str2) != 1)
    FAIL ();

  /* Constant literals passed directly are always ok
     (even with warnings about possible bugs from GCC).  */
  if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14
      || n1 != 7 || n2 != 14)
    FAIL ();

  /* In this case the format string is not known at compile time,
     but resides in read-only memory, so is ok.  */
  if (printf (str3, str4, &n1, str5, &n2) != 14
      || n1 != 7 || n2 != 14)
    FAIL ();

  strcpy (buf2 + 2, "%n%s%n");
  /* When the format string is writable and contains %n,
     with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
  CHK_FAIL2_START
  if (printf (buf2, str4, &n1, str5, &n1) != 14)
    FAIL ();
  CHK_FAIL2_END

  /* But if there is no %n, even writable format string
     should work.  */
  buf2[6] = '\0';
  if (printf (buf2 + 4, str5) != 7)
    FAIL ();

  FILE *fp = stdout;

  /* Constant literals passed directly are always ok
     (even with warnings about possible bugs from GCC).  */
  if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14
      || n1 != 7 || n2 != 14)
    FAIL ();

  /* In this case the format string is not known at compile time,
     but resides in read-only memory, so is ok.  */
  if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14
      || n1 != 7 || n2 != 14)
    FAIL ();

  strcpy (buf2 + 2, "%n%s%n");
  /* When the format string is writable and contains %n,
     with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
  CHK_FAIL2_START
  if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14)
    FAIL ();
  CHK_FAIL2_END

  /* But if there is no %n, even writable format string
     should work.  */
  buf2[6] = '\0';
  if (fprintf (fp, buf2 + 4, str5) != 7)
    FAIL ();

  if (freopen (temp_filename, "r", stdin) == NULL)
    {
      puts ("could not open temporary file");
      exit (1);
    }

  if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9))
    FAIL ();
  if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10))
    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (gets (buf) != buf)
    FAIL ();
  CHK_FAIL_END
#endif

  rewind (stdin);

  if (fgets (buf, sizeof (buf), stdin) != buf
      || memcmp (buf, "abcdefgh\n", 10))
    FAIL ();
  if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
    FAIL ();

  rewind (stdin);

  if (fgets (buf, l0 + sizeof (buf), stdin) != buf
      || memcmp (buf, "abcdefgh\n", 10))
    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (fgets (buf, sizeof (buf) + 1, stdin) != buf)
    FAIL ();
  CHK_FAIL_END

  CHK_FAIL_START
  if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf)
    FAIL ();
  CHK_FAIL_END
#endif

  rewind (stdin);

  if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
      || memcmp (buf, "abcdefgh\n", 10))
    FAIL ();
  if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
      || memcmp (buf, "ABCDEFGHI", 10))
    FAIL ();

  rewind (stdin);

  if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf
      || memcmp (buf, "abcdefgh\n", 10))
    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf)
    FAIL ();
  CHK_FAIL_END

  CHK_FAIL_START
  if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf)
    FAIL ();
  CHK_FAIL_END
#endif

  lseek (fileno (stdin), 0, SEEK_SET);

  if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
      || memcmp (buf, "abcdefgh\n", 9))
    FAIL ();
  if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
      || memcmp (buf, "ABCDEFGHI", 9))
    FAIL ();

  lseek (fileno (stdin), 0, SEEK_SET);

  if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1
      || memcmp (buf, "abcdefgh\n", 9))
    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
    FAIL ();
  CHK_FAIL_END
#endif

  if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
      != sizeof (buf) - 1
      || memcmp (buf, "\nABCDEFGH", 9))
    FAIL ();
  if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
      || memcmp (buf, "abcdefgh\n", 9))
    FAIL ();
  if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
      != sizeof (buf) - 1
      || memcmp (buf, "h\nABCDEFG", 9))
    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
      != sizeof (buf) + 1)
    FAIL ();
  CHK_FAIL_END
#endif

  if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
      != sizeof (buf) - 1
      || memcmp (buf, "\nABCDEFGH", 9))
    FAIL ();
  if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
      || memcmp (buf, "abcdefgh\n", 9))
    FAIL ();
  if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
      != sizeof (buf) - 1
      || memcmp (buf, "h\nABCDEFG", 9))
    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
      != sizeof (buf) + 1)
    FAIL ();
  CHK_FAIL_END
#endif

  if (freopen (temp_filename, "r", stdin) == NULL)
    {
      puts ("could not open temporary file");
      exit (1);
    }

  if (fseek (stdin, 9 + 10 + 11, SEEK_SET))
    {
      puts ("could not seek in test file");
      exit (1);
    }

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (gets (buf) != buf)
    FAIL ();
  CHK_FAIL_END
#endif

  /* Check whether missing N$ formats are detected.  */
  CHK_FAIL2_START
  printf ("%3$d\n", 1, 2, 3, 4);
  CHK_FAIL2_END

  CHK_FAIL2_START
  fprintf (stdout, "%3$d\n", 1, 2, 3, 4);
  CHK_FAIL2_END

  CHK_FAIL2_START
  sprintf (buf, "%3$d\n", 1, 2, 3, 4);
  CHK_FAIL2_END

  CHK_FAIL2_START
  snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
  CHK_FAIL2_END

  int sp[2];
  if (socketpair (PF_UNIX, SOCK_STREAM, 0, sp))
    FAIL ();
  else
    {
      const char *sendstr = "abcdefgh\nABCDEFGH\n0123456789\n";
      if (send (sp[0], sendstr, strlen (sendstr), 0) != strlen (sendstr))
	FAIL ();

      char recvbuf[12];
      if (recv (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK)
	  != sizeof recvbuf
	  || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
	FAIL ();

      if (recv (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK)
	  != sizeof recvbuf - 7
	  || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      if (recv (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK)
	  != sizeof recvbuf)
	FAIL ();
      CHK_FAIL_END

      CHK_FAIL_START
      if (recv (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK)
	  != sizeof recvbuf - 3)
	FAIL ();
      CHK_FAIL_END
#endif

      socklen_t sl;
      struct sockaddr_un sa_un;

      sl = sizeof (sa_un);
      if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
	  != sizeof recvbuf
	  || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
	FAIL ();

      sl = sizeof (sa_un);
      if (recvfrom (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK,
	  &sa_un, &sl) != sizeof recvbuf - 7
	  || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      sl = sizeof (sa_un);
      if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
	  != sizeof recvbuf)
	FAIL ();
      CHK_FAIL_END

      CHK_FAIL_START
      sl = sizeof (sa_un);
      if (recvfrom (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK,
	  &sa_un, &sl) != sizeof recvbuf - 3)
	FAIL ();
      CHK_FAIL_END
#endif

      close (sp[0]);
      close (sp[1]);
    }

  char fname[] = "/tmp/tst-chk1-dir-XXXXXX\0foo";
  char *enddir = strchr (fname, '\0');
  if (mkdtemp (fname) == NULL)
    {
      printf ("mkdtemp failed: %m\n");
      return 1;
    }
  *enddir = '/';
  if (symlink ("bar", fname) != 0)
    FAIL ();

  char readlinkbuf[4];
  if (readlink (fname, readlinkbuf, 4) != 3
      || memcmp (readlinkbuf, "bar", 3) != 0)
    FAIL ();
  if (readlink (fname, readlinkbuf + 1, l0 + 3) != 3
      || memcmp (readlinkbuf, "bbar", 4) != 0)
    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  if (readlink (fname, readlinkbuf + 2, l0 + 3) != 3)
    FAIL ();
  CHK_FAIL_END

  CHK_FAIL_START
  if (readlink (fname, readlinkbuf + 3, 4) != 3)
    FAIL ();
  CHK_FAIL_END
#endif

  char *cwd1 = getcwd (NULL, 0);
  if (cwd1 == NULL)
    FAIL ();

  char *cwd2 = getcwd (NULL, 250);
  if (cwd2 == NULL)
    FAIL ();

  if (cwd1 && cwd2)
    {
      if (strcmp (cwd1, cwd2) != 0)
	FAIL ();

      *enddir = '\0';
      if (chdir (fname))
	FAIL ();

      char *cwd3 = getcwd (NULL, 0);
      if (cwd3 == NULL)
	FAIL ();
      if (strcmp (fname, cwd3) != 0)
	printf ("getcwd after chdir is '%s' != '%s',"
		"get{c,}wd tests skipped\n", cwd3, fname);
      else
	{
	  char getcwdbuf[sizeof fname - 3];

	  char *cwd4 = getcwd (getcwdbuf, sizeof getcwdbuf);
	  if (cwd4 != getcwdbuf
	      || strcmp (getcwdbuf, fname) != 0)
	    FAIL ();

	  cwd4 = getcwd (getcwdbuf + 1, l0 + sizeof getcwdbuf - 1);
	  if (cwd4 != getcwdbuf + 1
	      || getcwdbuf[0] != fname[0]
	      || strcmp (getcwdbuf + 1, fname) != 0)
	    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
	  CHK_FAIL_START
	  if (getcwd (getcwdbuf + 2, l0 + sizeof getcwdbuf)
	      != getcwdbuf + 2)
	    FAIL ();
	  CHK_FAIL_END

	  CHK_FAIL_START
	  if (getcwd (getcwdbuf + 2, sizeof getcwdbuf)
	      != getcwdbuf + 2)
	    FAIL ();
	  CHK_FAIL_END
#endif

	  if (getwd (getcwdbuf) != getcwdbuf
	      || strcmp (getcwdbuf, fname) != 0)
	    FAIL ();

	  if (getwd (getcwdbuf + 1) != getcwdbuf + 1
	      || strcmp (getcwdbuf + 1, fname) != 0)
	    FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
	  CHK_FAIL_START
	  if (getwd (getcwdbuf + 2) != getcwdbuf + 2)
	    FAIL ();
	  CHK_FAIL_END
#endif
	}

      if (chdir (cwd1) != 0)
	FAIL ();
      free (cwd3);
    }

  free (cwd1);
  free (cwd2);
  *enddir = '/';
  if (unlink (fname) != 0)
    FAIL ();

  *enddir = '\0';
  if (rmdir (fname) != 0)
    FAIL ();


#if PATH_MAX > 0
  char largebuf[PATH_MAX];
  char *realres = realpath (".", largebuf);
  if (realres != largebuf)
    FAIL ();

# if __USE_FORTIFY_LEVEL >= 1
  CHK_FAIL_START
  char realbuf[1];
  realres = realpath (".", realbuf);
  if (realres != realbuf)
    FAIL ();
  CHK_FAIL_END
# endif
#endif

  if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
    {
      assert (MB_CUR_MAX <= 10);

      /* First a simple test.  */
      char enough[10];
      if (wctomb (enough, L'A') != 1)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      /* We know the wchar_t encoding is ISO 10646.  So pick a
	 character which has a multibyte representation which does not
	 fit.  */
      CHK_FAIL_START
      char smallbuf[2];
      if (wctomb (smallbuf, L'\x100') != 2)
	FAIL ();
      CHK_FAIL_END
#endif

      mbstate_t s;
      memset (&s, '\0', sizeof (s));
      if (wcrtomb (enough, L'D', &s) != 1 || enough[0] != 'D')
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      /* We know the wchar_t encoding is ISO 10646.  So pick a
	 character which has a multibyte representation which does not
	 fit.  */
      CHK_FAIL_START
      char smallbuf[2];
      if (wcrtomb (smallbuf, L'\x100', &s) != 2)
	FAIL ();
      CHK_FAIL_END
#endif

      wchar_t wenough[10];
      memset (&s, '\0', sizeof (s));
      const char *cp = "A";
      if (mbsrtowcs (wenough, &cp, 10, &s) != 1
	  || wcscmp (wenough, L"A") != 0)
	FAIL ();

      cp = "BC";
      if (mbsrtowcs (wenough, &cp, l0 + 10, &s) != 2
	  || wcscmp (wenough, L"BC") != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      wchar_t wsmallbuf[2];
      cp = "ABC";
      mbsrtowcs (wsmallbuf, &cp, 10, &s);
      CHK_FAIL_END
#endif

      cp = "A";
      if (mbstowcs (wenough, cp, 10) != 1
	  || wcscmp (wenough, L"A") != 0)
	FAIL ();

      cp = "DEF";
      if (mbstowcs (wenough, cp, l0 + 10) != 3
	  || wcscmp (wenough, L"DEF") != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      wchar_t wsmallbuf[2];
      cp = "ABC";
      mbstowcs (wsmallbuf, cp, 10);
      CHK_FAIL_END
#endif

      memset (&s, '\0', sizeof (s));
      cp = "ABC";
      wcscpy (wenough, L"DEF");
      if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1
	  || wcscmp (wenough, L"AEF") != 0)
	FAIL ();

      cp = "IJ";
      if (mbsnrtowcs (wenough, &cp, 1, l0 + 10, &s) != 1
	  || wcscmp (wenough, L"IEF") != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      wchar_t wsmallbuf[2];
      cp = "ABC";
      mbsnrtowcs (wsmallbuf, &cp, 3, 10, &s);
      CHK_FAIL_END
#endif

      memset (&s, '\0', sizeof (s));
      const wchar_t *wcp = L"A";
      if (wcsrtombs (enough, &wcp, 10, &s) != 1
	  || strcmp (enough, "A") != 0)
	FAIL ();

      wcp = L"BC";
      if (wcsrtombs (enough, &wcp, l0 + 10, &s) != 2
	  || strcmp (enough, "BC") != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      char smallbuf[2];
      wcp = L"ABC";
      wcsrtombs (smallbuf, &wcp, 10, &s);
      CHK_FAIL_END
#endif

      memset (enough, 'Z', sizeof (enough));
      wcp = L"EF";
      if (wcstombs (enough, wcp, 10) != 2
	  || strcmp (enough, "EF") != 0)
	FAIL ();

      wcp = L"G";
      if (wcstombs (enough, wcp, l0 + 10) != 1
	  || strcmp (enough, "G") != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      char smallbuf[2];
      wcp = L"ABC";
      wcstombs (smallbuf, wcp, 10);
      CHK_FAIL_END
#endif

      memset (&s, '\0', sizeof (s));
      wcp = L"AB";
      if (wcsnrtombs (enough, &wcp, 1, 10, &s) != 1
	  || strcmp (enough, "A") != 0)
	FAIL ();

      wcp = L"BCD";
      if (wcsnrtombs (enough, &wcp, 1, l0 + 10, &s) != 1
	  || strcmp (enough, "B") != 0)
	FAIL ();

#if __USE_FORTIFY_LEVEL >= 1
      CHK_FAIL_START
      char smallbuf[2];
      wcp = L"ABC";
      wcsnrtombs (smallbuf, &wcp, 3, 10, &s);
      CHK_FAIL_END
#endif
    }
Exemplo n.º 14
0
int
main(int argc, char *argv[])
{
	char srcbuf[128];
	wchar_t dstbuf[128];
	char *src;
	mbstate_t s;

	/*
	 * C/POSIX locale.
	 */

	printf("1..1\n");

	/* Simple null terminated string. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
	    sizeof(*dstbuf), &s) == 5);
	assert(wcscmp(dstbuf, L"hello") == 0);
	assert(dstbuf[6] == 0xcccc);
	assert(src == NULL);

	/* Simple null terminated string, stopping early. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 4, sizeof(dstbuf) /
	    sizeof(*dstbuf), &s) == 4);
	assert(wmemcmp(dstbuf, L"hell", 4) == 0);
	assert(dstbuf[5] == 0xcccc);
	assert(src == srcbuf + 4);

	/* Not enough space in destination buffer. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, 4, &s) == 4);
	assert(wmemcmp(dstbuf, L"hell", 4) == 0);
	assert(dstbuf[5] == 0xcccc);
	assert(src == srcbuf + 4);

	/* Null terminated string, internal dest. buffer */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	assert(mbsnrtowcs(NULL, (const char **)&src, 6, 0, &s) == 5);

	/* Null terminated string, internal dest. buffer, stopping early */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	assert(mbsnrtowcs(NULL, (const char **)&src, 4, 0, &s) == 4);

	/* Null terminated string, internal state. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	src = srcbuf;
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
	    sizeof(*dstbuf), NULL) == 5);
	assert(wcscmp(dstbuf, L"hello") == 0);
	assert(dstbuf[6] == 0xcccc);
	assert(src == NULL);

	/* Null terminated string, internal state, internal dest. buffer. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	src = srcbuf;
	assert(mbsnrtowcs(NULL, (const char **)&src, 6, 0, NULL) == 5);

	/* Empty source buffer. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	srcbuf[0] = '\0';
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, 1, &s) == 0);
	assert(dstbuf[0] == 0);
	assert(dstbuf[1] == 0xcccc);
	assert(src == NULL);

	/* Zero length destination buffer. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "hello");
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, 0, &s) == 0);
	assert(dstbuf[0] == 0xcccc);
	assert(src == srcbuf);

	/* Zero length source buffer. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 0, 1, &s) == 0);
	assert(dstbuf[0] == 0xcccc);
	assert(src == srcbuf);

	/*
	 * Japanese (EUC) locale.
	 */

	assert(strcmp(setlocale(LC_CTYPE, "ja_JP.eucJP"), "ja_JP.eucJP") == 0);
	assert(MB_CUR_MAX > 1);

	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 8, sizeof(dstbuf) /
	    sizeof(*dstbuf), &s) == 5);
	assert(dstbuf[0] == 0xA3C1 && dstbuf[1] == 0x20 && dstbuf[2] == 0x42 &&
	    dstbuf[3] == 0x20 && dstbuf[4] == 0xA3C3 && dstbuf[5] == 0);
	assert(src == NULL);

	/* Partial character. */
	memset(srcbuf, 0xcc, sizeof(srcbuf));
	strcpy(srcbuf, "\xA3\xC1 B \xA3\xC3");
	src = srcbuf;
	memset(&s, 0, sizeof(s));
	wmemset(dstbuf, 0xcccc, sizeof(dstbuf) / sizeof(*dstbuf));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 6, sizeof(dstbuf) /
	    sizeof(*dstbuf), &s) == 4);
	assert(src == srcbuf + 6);
	assert(!mbsinit(&s));
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
	    sizeof(*dstbuf), &s) == 1);
	assert(src == srcbuf + 7);
	assert(mbsnrtowcs(dstbuf, (const char **)&src, 1, sizeof(dstbuf) /
	    sizeof(*dstbuf), &s) == 0);
	assert(src == NULL);

	printf("ok 1 - mbsnrtowcs()\n");

	return (0);
}
/**
 * Decodes an (external) UTF-8 Unicode multibyte character stream into an (internal) UTF-32 Unicode wide character vector.
 *
 * @param p0 the destination wide character array (Hand over as reference!)
 * @param p1 the destination wide character array count
 * @param p2 the destination wide character array size
 * @param p3 the source UTF-8 Unicode multibyte character stream
 * @param p4 the source UTF-8 Unicode multibyte character stream count
 */
void decode_utf_8_unicode_character_vector(void* p0, void* p1, void* p2, void* p3, void* p4) {

    if (p4 != *NULL_POINTER_MEMORY_MODEL) {

        int* sc = (int*) p4;

        if (p3 != *NULL_POINTER_MEMORY_MODEL) {

            char* s = (char*) p3;

            if (p2 != *NULL_POINTER_MEMORY_MODEL) {

                int* ds = (int*) p2;

                if (p1 != *NULL_POINTER_MEMORY_MODEL) {

                    int* dc = (int*) p1;

                    if (p0 != *NULL_POINTER_MEMORY_MODEL) {

                        wchar_t** d = (wchar_t**) p0;

                        if (*dc >= *NUMBER_0_INTEGER_MEMORY_MODEL) {

                            log_terminated_message((void*) INFORMATION_LEVEL_LOG_MODEL, (void*) L"Decode UTF-8 Unicode character vector.");

                            // The new destination wide character vector size.
                            //
                            // CAUTION! The "worst case" is assumed, i.e. that each source character
                            // represents an ascii character encoded by utf-8 with ONE single byte.
                            // Therefore, the destination size is adjusted accordingly.
                            // In case not all source characters are ascii characters -- even better,
                            // since then more than just one source character were used for encoding,
                            // and the destination wide character array will have LESS entries (count)
                            // than the destination size that was set before.
                            // In this case, the destination size will be too big, but can be reduced
                            // to the actual destination count below, if so wanted.
                            *ds = *dc + (*sc * *NUMBER_1_INTEGER_MEMORY_MODEL);

                            // Reallocate destination wide character vector.
                            reallocate_array(p0, p1, p2, (void*) WIDE_CHARACTER_PRIMITIVE_MEMORY_ABSTRACTION);

                            // Set locale.
                            //
                            // Possible locales are: LANG, LC_CTYPE, ..., LC_ALL
                            // where LANG has the lowest and LC_ALL the highest priority.
                            // That is, if LC_ALL is specified, it overwrites e.g. the LC_CTYPE setting.
                            // If no value "" is given, the default will be used.
                            // Note, that LC_CTYPE suffices for the purpose of character conversion,
                            // since it is the category that applies to classification and conversion
                            // of characters, and to multibyte and wide characters.
                            //
                            // CAUTION! This setting is necessary for UTF-8 Unicode character conversion
                            // with restartable multibyte conversion functions like "mbsnrtowcs"
                            // and "wcsnrtombs" to work correctly.
                            // The return value is not used; this is a global setting.
                            char* loc = setlocale(LC_CTYPE, "");

                            // The state of the conversion.
                            //
                            // Certain character sets use a stateful encoding.
                            // That is, the encoded values depend in some way
                            // on the previous bytes in the text.
                            //
                            // Since the conversion functions allow converting a text
                            // in more than one step, there must be a way to pass this
                            // information from one call of the functions to another.
                            //
                            // A variable of type mbstate_t can contain all the
                            // information about the shift state needed from one call
                            // to a conversion function to another.
//??                            mbstate_t st;

                            // Clear the whole conversion state variable.
                            //
                            // There is no specific function or initializer to put the
                            // state object in any specific state. The rules are that
                            // the object should always represent the initial state
                            // before the first use and this is achieved here.
//??                            memreplace((void*) &st, '\0', *MULTIBYTE_CHARACTER_STATE_CONVERSION_TYPE_SIZE);

                            // Initialise error number.
                            // It is a global variable/ function and other operations
                            // may have set some value that is not wanted here.
                            //
                            // CAUTION! Initialise the error number BEFORE calling the function
                            // that might cause an error.
                            errno = *NUMBER_0_INTEGER_MEMORY_MODEL;

                            // Converts the multibyte character string into a wide character string.
                            //
                            // Returns the number of wide characters converted.
//??                            int n = mbsnrtowcs(*d, &s, *sc, *ds, &st);
                            int n = mbsnrtowcs(*d, (const char**) &s, *sc, *ds, *NULL_POINTER_MEMORY_MODEL);

                            if (n >= *NUMBER_0_INTEGER_MEMORY_MODEL) {

                                // Increment destination count by the number of wide characters converted.
                                *dc = *dc + n;

                            } else {

                                if (errno == EILSEQ) {

        fwprintf(stdout, L"TEST ERROR EILSEQ errno: %i\n", errno);
                                    log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. The input string contains an invalid multibyte sequence.");

                                } else {

        fwprintf(stdout, L"TEST ERROR UNKNOWN errno: %i\n", errno);
                                    log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. An unknown error occured.");
                                }
                            }

                        } else {

                            log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. The destination count is negative.");
                        }

                    } else {

                        log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. The destination is null.");
                    }

                } else {

                    log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. The destination count is null.");
                }

            } else {

                log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. The destination size is null.");
            }

        } else {

            log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. The source is null.");
        }

    } else {

        log_terminated_message((void*) ERROR_LEVEL_LOG_MODEL, (void*) L"Could not decode utf-8 unicode character stream. The source count is null.");
    }
}
Exemplo n.º 16
0
	void WString::prepareWString(const AnyString& string, bool uncprefix)
	{
		if (string.empty())
		{
			if (uncprefix)
			{
				pSize = 4;
				pWString = (wchar_t*)::realloc(pWString, sizeof(wchar_t) * 5);
				pWString[0] = L'\\';
				pWString[1] = L'\\';
				pWString[2] = L'?';
				pWString[3] = L'\\';
				pWString[4] = L'\0';
			}
			else
				clear();
			return;
		}

		if (string.size() > INT_MAX)
		{
			clear();
			return;
		}

		// Offset according to the presence of the UNC prefix
		const uint offset = (not uncprefix) ? 0 : 4;

		#ifdef YUNI_OS_WINDOWS
		{
			// Allocate and convert the C-String. Several iterations may be required
			// for allocating enough room for the conversion.
			const int sizeRequired = MultiByteToWideChar(CP_UTF8, 0, string.c_str(), string.size(), nullptr, 0);
			if (sizeRequired <= 0)
			{
				clear();
				return;
			}

			pSize = sizeRequired + offset;

			pWString = (wchar_t*) realloc(pWString, sizeof(wchar_t) * (pSize + 1));
			if (nullptr == pWString) // Impossible to allocate the buffer. Aborting.
			{
				clear();
				return;
			}

			// Converting into Wide String
			const int n = MultiByteToWideChar(CP_UTF8, 0, string.c_str(), static_cast<int>(string.size()), pWString + offset, static_cast<int>(pSize - offset));
			if (n != sizeRequired)
			{
				assert(false and "most likely an error");
				clear();
				return;
			}
		}
		#else
		{
			const char* wcstr = string.c_str();

			mbstate_t state;
			memset (&state, '\0', sizeof (state));

			size_t sizeRequired = mbsnrtowcs(nullptr, &wcstr, string.size(), 0, &state);
			if (0 == sizeRequired or (size_t) -1 == sizeRequired)
			{
				clear();
				return;
			}

			pSize = sizeRequired + offset;

			pWString = (wchar_t*) realloc(pWString, sizeof(wchar_t) * (pSize + 1));
			if (nullptr == pWString) // Impossible to allocate the buffer. Aborting.
			{
				clear();
				return;
			}

			memset (&state, '\0', sizeof (state));
			size_t written = mbsnrtowcs(pWString + offset, &wcstr, string.size(), pSize - offset, &state);
			if (0 == written or (size_t) -1 == written)
			{
				clear();
				return;
			}
		}
		#endif


		// prepend the Windows UNC prefix
		if (uncprefix)
		{
			pWString[0] = L'\\';
			pWString[1] = L'\\';
			pWString[2] = L'?';
			pWString[3] = L'\\';
		}

		// always ensure that the string is zero terminated
		pWString[pSize] = L'\0';
	}