1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2026 Hans Rosenfeld 14 */ 15 16 /* 17 * Regression test for illumos #17781. The refactoring of the various *printf 18 * functions in #17182 missed a corner case of [v]swprintf(), which need to go 19 * through a special code path in _ndoprnt() using wmemcpy() for output into 20 * string rather than wctomb(). This is indicated by the _IOREAD flag on the 21 * temporary FILE created by vswprintf() for the output string, but the check 22 * in _ndoprnt() erroneously insisted that this is the only flag set. 23 * 24 * As a result, [v]swprintf() write multibyte characters according to the 25 * LC_CTYPE of the current locale, instead of wchar_t as they ought to. 26 */ 27 28 #include <sys/sysmacros.h> 29 #include <string.h> 30 #include <stdio.h> 31 #include <wchar.h> 32 33 wchar_t foo[] = L"bl0rg"; 34 wchar_t bar[6]; 35 36 void 37 hexdump(char *buf, int len) 38 { 39 int i; 40 41 for (i = 0; i != len; i++) 42 fprintf(stderr, "%02x ", buf[i]); 43 } 44 45 int 46 main(int argc, char **argv) 47 { 48 int len; 49 50 len = swprintf(bar, ARRAY_SIZE(bar), L"%ls", foo); 51 52 if (len != ARRAY_SIZE(foo) - 1) { 53 fprintf(stderr, "length mismatch: expected %d != actual %d", 54 ARRAY_SIZE(foo) - 1, len); 55 return (1); 56 } 57 58 if (memcmp(foo, bar, sizeof (foo)) != 0) { 59 fprintf(stderr, "output mismatch:\n"); 60 fprintf(stderr, "expected: "); 61 hexdump((char *)foo, sizeof (foo)); 62 fprintf(stderr, "\n"); 63 fprintf(stderr, "actual: "); 64 hexdump((char *)bar, sizeof (bar)); 65 fprintf(stderr, "\n"); 66 67 return (1); 68 } 69 70 return (0); 71 } 72