1 /* $NetBSD: t_ctype.c,v 1.12 2025/09/15 00:11:55 riastradh Exp $ */ 2 3 /*- 4 * Copyright (c) 2025 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* 30 * Tests for the ctype(3) character classification macros. 31 * 32 * NOTE: These tests intentionally trigger undefined behaviour by 33 * passing int values to the ctype(3) functions which are neither EOF 34 * nor representable by unsigned char. The purpose is to verify 35 * NetBSD's intentional trapping of this undefined behaviour -- or 36 * intentional allowing of this undefined behaviour, when the 37 * environment variable LIBC_ALLOWCTYPEABUSE is set. 38 */ 39 40 #include <sys/cdefs.h> 41 __RCSID("$NetBSD: t_ctype.c,v 1.12 2025/09/15 00:11:55 riastradh Exp $"); 42 43 #include <sys/wait.h> 44 45 #include <atf-c.h> 46 #include <ctype.h> 47 #include <locale.h> 48 #include <limits.h> 49 #include <setjmp.h> 50 #include <signal.h> 51 #include <stdio.h> 52 #include <unistd.h> 53 54 #include "h_macros.h" 55 56 #ifdef __CHAR_UNSIGNED__ 57 enum { CHAR_UNSIGNED = 1 }; 58 #else 59 enum { CHAR_UNSIGNED = 0 }; 60 #endif 61 62 /* 63 * libc has a guard page for the LC_CTYPE=C ctype(3) tables only on 64 * some platforms. We skip it if char is unsigned (in which case the 65 * common kind of ctype(3) abuse is unlikely). We also skip it in 66 * static builds -- this is determined in the Makefile. 67 */ 68 #ifndef _CTYPE_GUARD_PAGE 69 # ifdef __CHAR_UNSIGNED__ 70 # define _CTYPE_GUARD_PAGE 0 71 # else 72 # define _CTYPE_GUARD_PAGE 1 73 # endif 74 #endif 75 76 static const char *const locales[] = { "C.UTF-8", "fr_FR.ISO8859-1", "C" }; 77 78 static int isalpha_wrapper(int ch) { return isalpha(ch); } 79 static int isupper_wrapper(int ch) { return isupper(ch); } 80 static int islower_wrapper(int ch) { return islower(ch); } 81 static int isdigit_wrapper(int ch) { return isdigit(ch); } 82 static int isxdigit_wrapper(int ch) { return isxdigit(ch); } 83 static int isalnum_wrapper(int ch) { return isalnum(ch); } 84 static int isspace_wrapper(int ch) { return isspace(ch); } 85 static int ispunct_wrapper(int ch) { return ispunct(ch); } 86 static int isprint_wrapper(int ch) { return isprint(ch); } 87 static int isgraph_wrapper(int ch) { return isgraph(ch); } 88 static int iscntrl_wrapper(int ch) { return iscntrl(ch); } 89 static int isblank_wrapper(int ch) { return isblank(ch); } 90 static int toupper_wrapper(int ch) { return toupper(ch); } 91 static int tolower_wrapper(int ch) { return tolower(ch); } 92 93 jmp_buf env; 94 95 static void 96 handle_signal(int signo) 97 { 98 99 longjmp(env, 1); 100 } 101 102 static void 103 test_abuse(const char *name, int (*ctypefn)(int)) 104 { 105 volatile int ch; /* for longjmp */ 106 107 for (ch = CHAR_MIN; ch < 0; ch++) { 108 volatile int result; 109 110 if (ch == EOF) 111 continue; 112 ATF_REQUIRE_MSG(ch != (int)(unsigned char)ch, "ch=%d", ch); 113 if (setjmp(env) == 0) { 114 REQUIRE_LIBC(signal(SIGABRT, &handle_signal), SIG_ERR); 115 REQUIRE_LIBC(signal(SIGSEGV, &handle_signal), SIG_ERR); 116 result = (*ctypefn)(ch); 117 REQUIRE_LIBC(signal(SIGABRT, SIG_DFL), SIG_ERR); 118 REQUIRE_LIBC(signal(SIGSEGV, SIG_DFL), SIG_ERR); 119 atf_tc_fail_nonfatal("%s failed to detect invalid %d," 120 " returned %d", 121 name, ch, result); 122 } else { 123 REQUIRE_LIBC(signal(SIGABRT, SIG_DFL), SIG_ERR); 124 REQUIRE_LIBC(signal(SIGSEGV, SIG_DFL), SIG_ERR); 125 } 126 } 127 128 for (; ch <= CHAR_MAX; ch++) 129 ATF_REQUIRE_MSG(ch == (int)(unsigned char)ch, "ch=%d", ch); 130 } 131 132 static void 133 test_abuse_in_locales(const char *name, int (*ctypefn)(int), bool macro) 134 { 135 size_t i; 136 137 for (i = 0; i < __arraycount(locales); i++) { 138 char buf[128]; 139 140 if (!_CTYPE_GUARD_PAGE && macro && 141 strcmp(locales[i], "C") == 0) { 142 fprintf(stderr, "skip LC_CTYPE=C ctype(3) abuse --" 143 " no libc guard page on this platform\n"); 144 } 145 146 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, locales[i]) != NULL, 147 "locales[i]=%s", locales[i]); 148 snprintf(buf, sizeof(buf), "[%s]%s", locales[i], name); 149 test_abuse(buf, ctypefn); 150 } 151 } 152 153 static void 154 test_use(const char *name, int (*ctypefn)(int)) 155 { 156 volatile int ch; /* for longjmp */ 157 158 for (ch = EOF; ch <= CHAR_MAX; ch = (ch == EOF ? 0 : ch + 1)) { 159 volatile int result; 160 161 if (setjmp(env) == 0) { 162 REQUIRE_LIBC(signal(SIGABRT, &handle_signal), SIG_ERR); 163 REQUIRE_LIBC(signal(SIGSEGV, &handle_signal), SIG_ERR); 164 result = (*ctypefn)(ch); 165 REQUIRE_LIBC(signal(SIGABRT, SIG_DFL), SIG_ERR); 166 REQUIRE_LIBC(signal(SIGSEGV, SIG_DFL), SIG_ERR); 167 (void)result; 168 } else { 169 REQUIRE_LIBC(signal(SIGABRT, SIG_DFL), SIG_ERR); 170 REQUIRE_LIBC(signal(SIGSEGV, SIG_DFL), SIG_ERR); 171 atf_tc_fail_nonfatal("%s(%d) raised SIGSEGV", 172 name, ch); 173 } 174 } 175 } 176 177 static void 178 test_isalpha_locale(const char *L, int (*ctypefn)(int)) 179 { 180 181 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 182 test_use("isalpha", ctypefn); 183 ATF_CHECK(!(*ctypefn)(EOF)); 184 } 185 186 static void 187 test_isupper_locale(const char *L, int (*ctypefn)(int)) 188 { 189 190 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 191 test_use("isupper", ctypefn); 192 ATF_CHECK(!(*ctypefn)(EOF)); 193 } 194 195 static void 196 test_islower_locale(const char *L, int (*ctypefn)(int)) 197 { 198 199 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 200 test_use("islower", ctypefn); 201 ATF_CHECK(!(*ctypefn)(EOF)); 202 } 203 204 static void 205 test_isdigit_locale(const char *L, int (*ctypefn)(int)) 206 { 207 208 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 209 test_use("isdigit", ctypefn); 210 ATF_CHECK(!(*ctypefn)(EOF)); 211 } 212 213 static void 214 test_isxdigit_locale(const char *L, int (*ctypefn)(int)) 215 { 216 217 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 218 test_use("isxdigit", ctypefn); 219 ATF_CHECK(!(*ctypefn)(EOF)); 220 } 221 222 static void 223 test_isalnum_locale(const char *L, int (*ctypefn)(int)) 224 { 225 226 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 227 test_use("isalnum", ctypefn); 228 ATF_CHECK(!(*ctypefn)(EOF)); 229 } 230 231 static void 232 test_isspace_locale(const char *L, int (*ctypefn)(int)) 233 { 234 235 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 236 test_use("isspace", ctypefn); 237 ATF_CHECK(!(*ctypefn)(EOF)); 238 } 239 240 static void 241 test_ispunct_locale(const char *L, int (*ctypefn)(int)) 242 { 243 244 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 245 test_use("ispunct", ctypefn); 246 ATF_CHECK(!(*ctypefn)(EOF)); 247 } 248 249 static void 250 test_isprint_locale(const char *L, int (*ctypefn)(int)) 251 { 252 253 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 254 test_use("isprint", ctypefn); 255 ATF_CHECK(!(*ctypefn)(EOF)); 256 } 257 258 static void 259 test_isgraph_locale(const char *L, int (*ctypefn)(int)) 260 { 261 262 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 263 test_use("isgraph", ctypefn); 264 ATF_CHECK(!(*ctypefn)(EOF)); 265 } 266 267 static void 268 test_iscntrl_locale(const char *L, int (*ctypefn)(int)) 269 { 270 271 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 272 test_use("iscntrl", ctypefn); 273 ATF_CHECK(!(*ctypefn)(EOF)); 274 } 275 276 static void 277 test_isblank_locale(const char *L, int (*ctypefn)(int)) 278 { 279 280 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 281 test_use("isblank", ctypefn); 282 ATF_CHECK(!(*ctypefn)(EOF)); 283 } 284 285 static void 286 test_toupper_locale(const char *L, int (*ctypefn)(int)) 287 { 288 int result; 289 290 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 291 test_use("toupper", ctypefn); 292 ATF_CHECK_MSG((result = (*ctypefn)(EOF)) == EOF, 293 "result=%d, expected EOF=%d", result, EOF); 294 } 295 296 static void 297 test_tolower_locale(const char *L, int (*ctypefn)(int)) 298 { 299 int result; 300 301 ATF_REQUIRE_MSG(setlocale(LC_CTYPE, L) != NULL, "L=%s", L); 302 test_use("tolower", ctypefn); 303 ATF_CHECK_MSG((result = (*ctypefn)(EOF)) == EOF, 304 "result=%d, expected EOF=%d", result, EOF); 305 } 306 307 static void 308 test_isalpha_c(int (*ctypefn)(int)) 309 { 310 int ch; 311 312 ATF_CHECK(!(*ctypefn)(EOF)); 313 for (ch = 0; ch <= UCHAR_MAX; ch++) { 314 switch (ch) { 315 case 'a': case 'A': 316 case 'b': case 'B': 317 case 'c': case 'C': 318 case 'd': case 'D': 319 case 'e': case 'E': 320 case 'f': case 'F': 321 case 'g': case 'G': 322 case 'h': case 'H': 323 case 'i': case 'I': 324 case 'j': case 'J': 325 case 'k': case 'K': 326 case 'l': case 'L': 327 case 'm': case 'M': 328 case 'n': case 'N': 329 case 'o': case 'O': 330 case 'p': case 'P': 331 case 'q': case 'Q': 332 case 'r': case 'R': 333 case 's': case 'S': 334 case 't': case 'T': 335 case 'u': case 'U': 336 case 'v': case 'V': 337 case 'w': case 'W': 338 case 'x': case 'X': 339 case 'y': case 'Y': 340 case 'z': case 'Z': 341 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 342 break; 343 default: 344 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 345 break; 346 } 347 } 348 } 349 350 static void 351 test_isupper_c(int (*ctypefn)(int)) 352 { 353 int ch; 354 355 ATF_CHECK(!(*ctypefn)(EOF)); 356 for (ch = 0; ch <= UCHAR_MAX; ch++) { 357 switch (ch) { 358 case 'A': 359 case 'B': 360 case 'C': 361 case 'D': 362 case 'E': 363 case 'F': 364 case 'G': 365 case 'H': 366 case 'I': 367 case 'J': 368 case 'K': 369 case 'L': 370 case 'M': 371 case 'N': 372 case 'O': 373 case 'P': 374 case 'Q': 375 case 'R': 376 case 'S': 377 case 'T': 378 case 'U': 379 case 'V': 380 case 'W': 381 case 'X': 382 case 'Y': 383 case 'Z': 384 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 385 break; 386 default: 387 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 388 break; 389 } 390 } 391 } 392 393 static void 394 test_islower_c(int (*ctypefn)(int)) 395 { 396 int ch; 397 398 ATF_CHECK(!(*ctypefn)(EOF)); 399 for (ch = 0; ch <= UCHAR_MAX; ch++) { 400 switch (ch) { 401 case 'a': 402 case 'b': 403 case 'c': 404 case 'd': 405 case 'e': 406 case 'f': 407 case 'g': 408 case 'h': 409 case 'i': 410 case 'j': 411 case 'k': 412 case 'l': 413 case 'm': 414 case 'n': 415 case 'o': 416 case 'p': 417 case 'q': 418 case 'r': 419 case 's': 420 case 't': 421 case 'u': 422 case 'v': 423 case 'w': 424 case 'x': 425 case 'y': 426 case 'z': 427 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 428 break; 429 default: 430 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 431 break; 432 } 433 } 434 } 435 436 static void 437 test_isdigit_c(int (*ctypefn)(int)) 438 { 439 int ch; 440 441 ATF_CHECK(!(*ctypefn)(EOF)); 442 for (ch = 0; ch <= UCHAR_MAX; ch++) { 443 switch (ch) { 444 case '0': 445 case '1': 446 case '2': 447 case '3': 448 case '4': 449 case '5': 450 case '6': 451 case '7': 452 case '8': 453 case '9': 454 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 455 break; 456 default: 457 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 458 break; 459 } 460 } 461 } 462 463 static void 464 test_isxdigit_c(int (*ctypefn)(int)) 465 { 466 int ch; 467 468 ATF_CHECK(!(*ctypefn)(EOF)); 469 for (ch = 0; ch <= UCHAR_MAX; ch++) { 470 switch (ch) { 471 case '0': 472 case '1': 473 case '2': 474 case '3': 475 case '4': 476 case '5': 477 case '6': 478 case '7': 479 case '8': 480 case '9': 481 case 'a': case 'A': 482 case 'b': case 'B': 483 case 'c': case 'C': 484 case 'd': case 'D': 485 case 'e': case 'E': 486 case 'f': case 'F': 487 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 488 break; 489 default: 490 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 491 break; 492 } 493 } 494 } 495 496 static void 497 test_isalnum_c(int (*ctypefn)(int)) 498 { 499 int ch; 500 501 ATF_CHECK(!(*ctypefn)(EOF)); 502 for (ch = 0; ch <= UCHAR_MAX; ch++) { 503 switch (ch) { 504 case 'a': case 'A': 505 case 'b': case 'B': 506 case 'c': case 'C': 507 case 'd': case 'D': 508 case 'e': case 'E': 509 case 'f': case 'F': 510 case 'g': case 'G': 511 case 'h': case 'H': 512 case 'i': case 'I': 513 case 'j': case 'J': 514 case 'k': case 'K': 515 case 'l': case 'L': 516 case 'm': case 'M': 517 case 'n': case 'N': 518 case 'o': case 'O': 519 case 'p': case 'P': 520 case 'q': case 'Q': 521 case 'r': case 'R': 522 case 's': case 'S': 523 case 't': case 'T': 524 case 'u': case 'U': 525 case 'v': case 'V': 526 case 'w': case 'W': 527 case 'x': case 'X': 528 case 'y': case 'Y': 529 case 'z': case 'Z': 530 case '0': 531 case '1': 532 case '2': 533 case '3': 534 case '4': 535 case '5': 536 case '6': 537 case '7': 538 case '8': 539 case '9': 540 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 541 break; 542 default: 543 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 544 break; 545 } 546 } 547 } 548 549 static void 550 test_isspace_c(int (*ctypefn)(int)) 551 { 552 int ch; 553 554 ATF_CHECK(!(*ctypefn)(EOF)); 555 for (ch = 0; ch <= UCHAR_MAX; ch++) { 556 switch (ch) { 557 case ' ': 558 case '\f': 559 case '\n': 560 case '\r': 561 case '\t': 562 case '\v': 563 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 564 break; 565 default: 566 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 567 break; 568 } 569 } 570 } 571 572 static void 573 test_ispunct_c(int (*ctypefn)(int)) 574 { 575 int ch; 576 577 ATF_CHECK(!(*ctypefn)(EOF)); 578 for (ch = 0; ch <= UCHAR_MAX; ch++) { 579 switch (ch) { 580 default: 581 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 582 break; 583 case 0 ... 0x1f: 584 case 0x20: /* space is printing but not punctuation */ 585 case 0x7f: 586 case 0x80 ... 0xff: 587 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 588 break; 589 case 'a': case 'A': 590 case 'b': case 'B': 591 case 'c': case 'C': 592 case 'd': case 'D': 593 case 'e': case 'E': 594 case 'f': case 'F': 595 case 'g': case 'G': 596 case 'h': case 'H': 597 case 'i': case 'I': 598 case 'j': case 'J': 599 case 'k': case 'K': 600 case 'l': case 'L': 601 case 'm': case 'M': 602 case 'n': case 'N': 603 case 'o': case 'O': 604 case 'p': case 'P': 605 case 'q': case 'Q': 606 case 'r': case 'R': 607 case 's': case 'S': 608 case 't': case 'T': 609 case 'u': case 'U': 610 case 'v': case 'V': 611 case 'w': case 'W': 612 case 'x': case 'X': 613 case 'y': case 'Y': 614 case 'z': case 'Z': 615 case '0': 616 case '1': 617 case '2': 618 case '3': 619 case '4': 620 case '5': 621 case '6': 622 case '7': 623 case '8': 624 case '9': 625 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 626 break; 627 } 628 } 629 } 630 631 static void 632 test_isprint_c(int (*ctypefn)(int)) 633 { 634 int ch; 635 636 ATF_CHECK(!(*ctypefn)(EOF)); 637 for (ch = 0; ch <= UCHAR_MAX; ch++) { 638 switch (ch) { 639 case 0x20: /* space is printing but not graphic */ 640 default: 641 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 642 break; 643 case 0 ... 0x1f: 644 case 0x7f: 645 case 0x80 ... 0xff: 646 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 647 break; 648 } 649 } 650 } 651 652 static void 653 test_isgraph_c(int (*ctypefn)(int)) 654 { 655 int ch; 656 657 ATF_CHECK(!(*ctypefn)(EOF)); 658 for (ch = 0; ch <= UCHAR_MAX; ch++) { 659 switch (ch) { 660 default: 661 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 662 break; 663 case 0 ... 0x1f: 664 case 0x20: /* space is printing but not graphic */ 665 case 0x7f: 666 case 0x80 ... 0xff: 667 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 668 break; 669 } 670 } 671 } 672 673 static void 674 test_iscntrl_c(int (*ctypefn)(int)) 675 { 676 int ch; 677 678 ATF_CHECK(!(*ctypefn)(EOF)); 679 for (ch = 0; ch <= UCHAR_MAX; ch++) { 680 switch (ch) { 681 case 0 ... 0x1f: 682 case 0x7f: 683 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 684 break; 685 default: 686 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 687 break; 688 } 689 } 690 } 691 692 static void 693 test_isblank_c(int (*ctypefn)(int)) 694 { 695 int ch; 696 697 ATF_CHECK(!(*ctypefn)(EOF)); 698 for (ch = 0; ch <= UCHAR_MAX; ch++) { 699 switch (ch) { 700 case ' ': 701 case '\t': 702 ATF_CHECK_MSG((*ctypefn)(ch), "ch=0x%x", ch); 703 break; 704 default: 705 ATF_CHECK_MSG(!(*ctypefn)(ch), "ch=0x%x", ch); 706 break; 707 } 708 } 709 } 710 711 static void 712 test_toupper_c(int (*ctypefn)(int)) 713 { 714 int ch, result, expected; 715 716 ATF_CHECK_MSG((result = (*ctypefn)(EOF)) == EOF, 717 "result=%d, expected EOF=%d", result, EOF); 718 for (ch = 0; ch <= UCHAR_MAX; ch++) { 719 switch (ch) { 720 case 'a': case 'A': expected = 'A'; break; 721 case 'b': case 'B': expected = 'B'; break; 722 case 'c': case 'C': expected = 'C'; break; 723 case 'd': case 'D': expected = 'D'; break; 724 case 'e': case 'E': expected = 'E'; break; 725 case 'f': case 'F': expected = 'F'; break; 726 case 'g': case 'G': expected = 'G'; break; 727 case 'h': case 'H': expected = 'H'; break; 728 case 'i': case 'I': expected = 'I'; break; 729 case 'j': case 'J': expected = 'J'; break; 730 case 'k': case 'K': expected = 'K'; break; 731 case 'l': case 'L': expected = 'L'; break; 732 case 'm': case 'M': expected = 'M'; break; 733 case 'n': case 'N': expected = 'N'; break; 734 case 'o': case 'O': expected = 'O'; break; 735 case 'p': case 'P': expected = 'P'; break; 736 case 'q': case 'Q': expected = 'Q'; break; 737 case 'r': case 'R': expected = 'R'; break; 738 case 's': case 'S': expected = 'S'; break; 739 case 't': case 'T': expected = 'T'; break; 740 case 'u': case 'U': expected = 'U'; break; 741 case 'v': case 'V': expected = 'V'; break; 742 case 'w': case 'W': expected = 'W'; break; 743 case 'x': case 'X': expected = 'X'; break; 744 case 'y': case 'Y': expected = 'Y'; break; 745 case 'z': case 'Z': expected = 'Z'; break; 746 default: 747 expected = ch; 748 break; 749 } 750 ATF_CHECK_MSG((result = (*ctypefn)(ch)) == expected, 751 "result=%d expected=%d", result, expected); 752 } 753 } 754 755 static void 756 test_tolower_c(int (*ctypefn)(int)) 757 { 758 int ch, result, expected; 759 760 ATF_CHECK_MSG((result = (*ctypefn)(EOF)) == EOF, 761 "result=%d, expected EOF=%d", result, EOF); 762 for (ch = 0; ch <= UCHAR_MAX; ch++) { 763 switch (ch) { 764 case 'a': case 'A': expected = 'a'; break; 765 case 'b': case 'B': expected = 'b'; break; 766 case 'c': case 'C': expected = 'c'; break; 767 case 'd': case 'D': expected = 'd'; break; 768 case 'e': case 'E': expected = 'e'; break; 769 case 'f': case 'F': expected = 'f'; break; 770 case 'g': case 'G': expected = 'g'; break; 771 case 'h': case 'H': expected = 'h'; break; 772 case 'i': case 'I': expected = 'i'; break; 773 case 'j': case 'J': expected = 'j'; break; 774 case 'k': case 'K': expected = 'k'; break; 775 case 'l': case 'L': expected = 'l'; break; 776 case 'm': case 'M': expected = 'm'; break; 777 case 'n': case 'N': expected = 'n'; break; 778 case 'o': case 'O': expected = 'o'; break; 779 case 'p': case 'P': expected = 'p'; break; 780 case 'q': case 'Q': expected = 'q'; break; 781 case 'r': case 'R': expected = 'r'; break; 782 case 's': case 'S': expected = 's'; break; 783 case 't': case 'T': expected = 't'; break; 784 case 'u': case 'U': expected = 'u'; break; 785 case 'v': case 'V': expected = 'v'; break; 786 case 'w': case 'W': expected = 'w'; break; 787 case 'x': case 'X': expected = 'x'; break; 788 case 'y': case 'Y': expected = 'y'; break; 789 case 'z': case 'Z': expected = 'z'; break; 790 default: 791 expected = ch; 792 break; 793 } 794 ATF_CHECK_MSG((result = (*ctypefn)(ch)) == expected, 795 "result=%d expected=%d", result, expected); 796 } 797 } 798 799 extern char **environ; 800 801 static void 802 test_abuse_override(const struct atf_tc *tc, const char *fn, const char *mode, 803 const char *locale) 804 { 805 char h_ctype_abuse[PATH_MAX]; 806 pid_t pid; 807 int status; 808 809 RL(snprintf(h_ctype_abuse, sizeof(h_ctype_abuse), "%s/h_ctype_abuse", 810 atf_tc_get_config_var(tc, "srcdir"))); 811 812 RL(setenv("LIBC_ALLOWCTYPEABUSE", "", 1)); 813 814 RL(pid = vfork()); 815 if (pid == 0) { /* child */ 816 char *const argv[] = { 817 h_ctype_abuse, 818 __UNCONST(fn), 819 __UNCONST(mode), 820 __UNCONST(locale), 821 NULL, 822 }; 823 824 if (execve(argv[0], argv, environ) == -1) 825 _exit(1); 826 _exit(2); 827 } 828 829 RL(waitpid(pid, &status, 0)); 830 if (WIFSIGNALED(status)) { 831 atf_tc_fail_nonfatal("child exited on signal %d (%s)", 832 WTERMSIG(status), strsignal(WTERMSIG(status))); 833 } else if (!WIFEXITED(status)) { 834 atf_tc_fail_nonfatal("child exited status=0x%x", status); 835 } else { 836 ATF_CHECK_MSG(WEXITSTATUS(status) == 0, 837 "child exited with code %d", 838 WEXITSTATUS(status)); 839 } 840 } 841 842 static void 843 test_abuse_override_in_locales(const struct atf_tc *tc, const char *fn, 844 const char *mode) 845 { 846 size_t i; 847 848 for (i = 0; i < __arraycount(locales); i++) { 849 fprintf(stderr, "# locale %s\n", locales[i]); 850 test_abuse_override(tc, fn, mode, locales[i]); 851 } 852 } 853 854 #define ADD_TEST_ABUSE(TP, FN) do \ 855 { \ 856 ATF_TP_ADD_TC(TP, abuse_##FN##_macro_c); \ 857 ATF_TP_ADD_TC(TP, abuse_##FN##_function_c); \ 858 ATF_TP_ADD_TC(TP, abuse_##FN##_macro_locale); \ 859 ATF_TP_ADD_TC(TP, abuse_##FN##_function_locale); \ 860 } while (0) 861 862 #define DEF_TEST_ABUSE(FN) \ 863 ATF_TC(abuse_##FN##_macro_c); \ 864 ATF_TC_HEAD(abuse_##FN##_macro_c, tc) \ 865 { \ 866 atf_tc_set_md_var(tc, "descr", \ 867 "Test abusing "#FN" macro with default LC_CTYPE=C"); \ 868 } \ 869 ATF_TC_BODY(abuse_##FN##_macro_c, tc) \ 870 { \ 871 if (CHAR_UNSIGNED) { \ 872 atf_tc_skip("runtime ctype(3) abuse is impossible with" \ 873 " unsigned char"); \ 874 } \ 875 if (!_CTYPE_GUARD_PAGE) \ 876 atf_tc_skip("no LC_CTYPE=C guard page on this platform"); \ 877 test_abuse(#FN, &FN##_wrapper); \ 878 } \ 879 ATF_TC(abuse_##FN##_function_c); \ 880 ATF_TC_HEAD(abuse_##FN##_function_c, tc) \ 881 { \ 882 atf_tc_set_md_var(tc, "descr", \ 883 "Test abusing "#FN" function with default LC_CTYPE=C"); \ 884 } \ 885 ATF_TC_BODY(abuse_##FN##_function_c, tc) \ 886 { \ 887 if (CHAR_UNSIGNED) { \ 888 atf_tc_skip("runtime ctype(3) abuse is impossible with" \ 889 " unsigned char"); \ 890 } \ 891 if (!_CTYPE_GUARD_PAGE) \ 892 atf_tc_skip("no LC_CTYPE=C guard page on this platform"); \ 893 test_abuse(#FN, &FN); \ 894 } \ 895 ATF_TC(abuse_##FN##_macro_locale); \ 896 ATF_TC_HEAD(abuse_##FN##_macro_locale, tc) \ 897 { \ 898 atf_tc_set_md_var(tc, "descr", \ 899 "Test abusing "#FN" macro with locales"); \ 900 } \ 901 ATF_TC_BODY(abuse_##FN##_macro_locale, tc) \ 902 { \ 903 if (CHAR_UNSIGNED) { \ 904 atf_tc_skip("runtime ctype(3) abuse is impossible with" \ 905 " unsigned char"); \ 906 } \ 907 test_abuse_in_locales(#FN, &FN##_wrapper, /*macro*/true); \ 908 } \ 909 ATF_TC(abuse_##FN##_function_locale); \ 910 ATF_TC_HEAD(abuse_##FN##_function_locale, tc) \ 911 { \ 912 atf_tc_set_md_var(tc, "descr", \ 913 "Test abusing "#FN" function with locales"); \ 914 } \ 915 ATF_TC_BODY(abuse_##FN##_function_locale, tc) \ 916 { \ 917 if (CHAR_UNSIGNED) { \ 918 atf_tc_skip("runtime ctype(3) abuse is impossible with" \ 919 " unsigned char"); \ 920 } \ 921 test_abuse_in_locales(#FN, &FN, /*macro*/false); \ 922 } 923 924 #define ADD_TEST_ABUSE_OVERRIDE(TP, FN) do \ 925 { \ 926 ATF_TP_ADD_TC(TP, abuse_override_##FN##_macro_c); \ 927 ATF_TP_ADD_TC(TP, abuse_override_##FN##_function_c); \ 928 ATF_TP_ADD_TC(TP, abuse_override_##FN##_macro_locale); \ 929 ATF_TP_ADD_TC(TP, abuse_override_##FN##_function_locale); \ 930 } while (0) 931 932 #define DEF_TEST_ABUSE_OVERRIDE(FN) \ 933 ATF_TC(abuse_override_##FN##_macro_c); \ 934 ATF_TC_HEAD(abuse_override_##FN##_macro_c, tc) \ 935 { \ 936 atf_tc_set_md_var(tc, "descr", \ 937 "Test allowing abuse of "#FN" macro with default LC_CTYPE=C"); \ 938 } \ 939 ATF_TC_BODY(abuse_override_##FN##_macro_c, tc) \ 940 { \ 941 test_abuse_override(tc, #FN, "macro", NULL); \ 942 } \ 943 ATF_TC(abuse_override_##FN##_function_c); \ 944 ATF_TC_HEAD(abuse_override_##FN##_function_c, tc) \ 945 { \ 946 atf_tc_set_md_var(tc, "descr", \ 947 "Test allowing abuse "#FN" function with default LC_CTYPE=C"); \ 948 } \ 949 ATF_TC_BODY(abuse_override_##FN##_function_c, tc) \ 950 { \ 951 test_abuse_override(tc, #FN, "function", NULL); \ 952 } \ 953 ATF_TC(abuse_override_##FN##_macro_locale); \ 954 ATF_TC_HEAD(abuse_override_##FN##_macro_locale, tc) \ 955 { \ 956 atf_tc_set_md_var(tc, "descr", \ 957 "Test allowing abuse of "#FN" macro with locales"); \ 958 } \ 959 ATF_TC_BODY(abuse_override_##FN##_macro_locale, tc) \ 960 { \ 961 test_abuse_override_in_locales(tc, #FN, "macro"); \ 962 } \ 963 ATF_TC(abuse_override_##FN##_function_locale); \ 964 ATF_TC_HEAD(abuse_override_##FN##_function_locale, tc) \ 965 { \ 966 atf_tc_set_md_var(tc, "descr", \ 967 "Test allowing abuse of "#FN" function with locales"); \ 968 } \ 969 ATF_TC_BODY(abuse_override_##FN##_function_locale, tc) \ 970 { \ 971 test_abuse_override_in_locales(tc, #FN, "function"); \ 972 } 973 974 #define ADD_TEST_USE(TP, FN) do \ 975 { \ 976 ATF_TP_ADD_TC(TP, FN##_macro_c); \ 977 ATF_TP_ADD_TC(TP, FN##_function_c); \ 978 ATF_TP_ADD_TC(TP, FN##_macro_locale); \ 979 ATF_TP_ADD_TC(TP, FN##_function_locale); \ 980 } while (0) 981 982 #define DEF_TEST_USE(FN) \ 983 ATF_TC(FN##_macro_c); \ 984 ATF_TC_HEAD(FN##_macro_c, tc) \ 985 { \ 986 atf_tc_set_md_var(tc, "descr", \ 987 "Test "#FN" macro with default LC_CTYPE=C"); \ 988 } \ 989 ATF_TC_BODY(FN##_macro_c, tc) \ 990 { \ 991 test_##FN##_c(&FN##_wrapper); \ 992 } \ 993 ATF_TC(FN##_function_c); \ 994 ATF_TC_HEAD(FN##_function_c, tc) \ 995 { \ 996 atf_tc_set_md_var(tc, "descr", \ 997 "Test "#FN" function with default LC_CTYPE=C"); \ 998 } \ 999 ATF_TC_BODY(FN##_function_c, tc) \ 1000 { \ 1001 test_##FN##_c(&FN); \ 1002 } \ 1003 ATF_TC(FN##_macro_locale); \ 1004 ATF_TC_HEAD(FN##_macro_locale, tc) \ 1005 { \ 1006 atf_tc_set_md_var(tc, "descr", \ 1007 "Test "#FN" macro with locales"); \ 1008 } \ 1009 ATF_TC_BODY(FN##_macro_locale, tc) \ 1010 { \ 1011 size_t i; \ 1012 \ 1013 for (i = 0; i < __arraycount(locales); i++) \ 1014 test_##FN##_locale(locales[i], &FN##_wrapper); \ 1015 } \ 1016 ATF_TC(FN##_function_locale); \ 1017 ATF_TC_HEAD(FN##_function_locale, tc) \ 1018 { \ 1019 atf_tc_set_md_var(tc, "descr", \ 1020 "Test "#FN" function with locales"); \ 1021 } \ 1022 ATF_TC_BODY(FN##_function_locale, tc) \ 1023 { \ 1024 size_t i; \ 1025 \ 1026 for (i = 0; i < __arraycount(locales); i++) \ 1027 test_##FN##_locale(locales[i], &FN); \ 1028 } 1029 1030 DEF_TEST_ABUSE(isalpha) 1031 DEF_TEST_ABUSE(isupper) 1032 DEF_TEST_ABUSE(islower) 1033 DEF_TEST_ABUSE(isdigit) 1034 DEF_TEST_ABUSE(isxdigit) 1035 DEF_TEST_ABUSE(isalnum) 1036 DEF_TEST_ABUSE(isspace) 1037 DEF_TEST_ABUSE(ispunct) 1038 DEF_TEST_ABUSE(isprint) 1039 DEF_TEST_ABUSE(isgraph) 1040 DEF_TEST_ABUSE(iscntrl) 1041 DEF_TEST_ABUSE(isblank) 1042 DEF_TEST_ABUSE(toupper) 1043 DEF_TEST_ABUSE(tolower) 1044 1045 DEF_TEST_ABUSE_OVERRIDE(isalpha) 1046 DEF_TEST_ABUSE_OVERRIDE(isupper) 1047 DEF_TEST_ABUSE_OVERRIDE(islower) 1048 DEF_TEST_ABUSE_OVERRIDE(isdigit) 1049 DEF_TEST_ABUSE_OVERRIDE(isxdigit) 1050 DEF_TEST_ABUSE_OVERRIDE(isalnum) 1051 DEF_TEST_ABUSE_OVERRIDE(isspace) 1052 DEF_TEST_ABUSE_OVERRIDE(ispunct) 1053 DEF_TEST_ABUSE_OVERRIDE(isprint) 1054 DEF_TEST_ABUSE_OVERRIDE(isgraph) 1055 DEF_TEST_ABUSE_OVERRIDE(iscntrl) 1056 DEF_TEST_ABUSE_OVERRIDE(isblank) 1057 DEF_TEST_ABUSE_OVERRIDE(toupper) 1058 DEF_TEST_ABUSE_OVERRIDE(tolower) 1059 1060 DEF_TEST_USE(isalpha) 1061 DEF_TEST_USE(isupper) 1062 DEF_TEST_USE(islower) 1063 DEF_TEST_USE(isdigit) 1064 DEF_TEST_USE(isxdigit) 1065 DEF_TEST_USE(isalnum) 1066 DEF_TEST_USE(isspace) 1067 DEF_TEST_USE(ispunct) 1068 DEF_TEST_USE(isprint) 1069 DEF_TEST_USE(isgraph) 1070 DEF_TEST_USE(iscntrl) 1071 DEF_TEST_USE(isblank) 1072 DEF_TEST_USE(toupper) 1073 DEF_TEST_USE(tolower) 1074 1075 ATF_TC(eof_confusion_iso8859_1); 1076 ATF_TC_HEAD(eof_confusion_iso8859_1, tc) 1077 { 1078 atf_tc_set_md_var(tc, "descr", 1079 "Test potential confusion with EOF in ISO-8859-1"); 1080 } 1081 ATF_TC_BODY(eof_confusion_iso8859_1, tc) 1082 { 1083 int ydots = 0xff; /* , LATIN SMALL LETTER Y WITH DIAERESIS */ 1084 int ch; 1085 1086 /* 1087 * The LATIN SMALL LETTER Y WITH DIAERESIS code point 0xff in 1088 * ISO-8859-1 is curious primarily because its bit pattern 1089 * coincides with an 8-bit signed -1, which is to say, EOF as 1090 * an 8-bit quantity; of course, for EOF, all of the is* 1091 * functions are supposed to return false (as we test above). 1092 * It also has the curious property that it lacks any 1093 * corresponding uppercase code point in ISO-8859-1, so we 1094 * can't distinguish it from EOF by tolower/toupper. 1095 */ 1096 ATF_REQUIRE(setlocale(LC_CTYPE, "fr_FR.ISO8859-1") != NULL); 1097 ATF_CHECK(isalpha(ydots)); 1098 ATF_CHECK(!isupper(ydots)); 1099 ATF_CHECK(islower(ydots)); 1100 ATF_CHECK(!isdigit(ydots)); 1101 ATF_CHECK(!isxdigit(ydots)); 1102 ATF_CHECK(isalnum(ydots)); 1103 ATF_CHECK(!isspace(ydots)); 1104 ATF_CHECK(!ispunct(ydots)); 1105 ATF_CHECK(isprint(ydots)); 1106 ATF_CHECK(isgraph(ydots)); 1107 ATF_CHECK(!iscntrl(ydots)); 1108 ATF_CHECK(!isblank(ydots)); 1109 ATF_CHECK_MSG((ch = toupper(ydots)) == ydots, "ch=0x%x", ch); 1110 ATF_CHECK_MSG((ch = tolower(ydots)) == ydots, "ch=0x%x", ch); 1111 } 1112 1113 ATF_TC(eof_confusion_koi8_u); 1114 ATF_TC_HEAD(eof_confusion_koi8_u, tc) 1115 { 1116 atf_tc_set_md_var(tc, "descr", 1117 "Test potential confusion with EOF in KOI8-U"); 1118 } 1119 ATF_TC_BODY(eof_confusion_koi8_u, tc) 1120 { 1121 int Hard = 0xff; /* , CYRILLIC CAPITAL LETTER HARD SIGN */ 1122 int hard = 0xdf; /* , CYRILLIC SMALL LETTER HARD SIGN */ 1123 int ch; 1124 1125 /* 1126 * The CYRILLIC CAPITAL LETTER HARD SIGN code point 0xff in 1127 * KOI8-U (and KOI8-R) also coincides with the bit pattern of 1128 * an 8-bit signed -1. Unlike LATIN SMALL LETTER Y WITH 1129 * DIAERESIS, it has a lowercase equivalent in KOI8-U. 1130 */ 1131 ATF_REQUIRE(setlocale(LC_CTYPE, "uk_UA.KOI8-U") != NULL); 1132 ATF_CHECK(isalpha(Hard)); 1133 ATF_CHECK(isupper(Hard)); 1134 ATF_CHECK(!islower(Hard)); 1135 ATF_CHECK(!isdigit(Hard)); 1136 ATF_CHECK(!isxdigit(Hard)); 1137 ATF_CHECK(isalnum(Hard)); 1138 ATF_CHECK(!isspace(Hard)); 1139 ATF_CHECK(!ispunct(Hard)); 1140 ATF_CHECK(isprint(Hard)); 1141 ATF_CHECK(isgraph(Hard)); 1142 ATF_CHECK(!iscntrl(Hard)); 1143 ATF_CHECK(!isblank(Hard)); 1144 ATF_CHECK_MSG((ch = toupper(Hard)) == Hard, "ch=0x%x", ch); 1145 ATF_CHECK_MSG((ch = tolower(Hard)) == hard, "ch=0x%x", ch); 1146 } 1147 1148 ATF_TC(eof_confusion_pt154); 1149 ATF_TC_HEAD(eof_confusion_pt154, tc) 1150 { 1151 atf_tc_set_md_var(tc, "descr", 1152 "Test potential confusion with EOF in PT154"); 1153 } 1154 ATF_TC_BODY(eof_confusion_pt154, tc) 1155 { 1156 int ya = 0xff; /* , CYRILLIC SMALL LETTER YA */ 1157 int Ya = 0xdf; /* , CYRILLIC CAPITAL LETTER YA */ 1158 int ch; 1159 1160 /* 1161 * The CYRILLIC SMALL LETTER YA code point 0xff in PT154 also 1162 * coincides with the bit pattern of an 8-bit signed -1, and is 1163 * lowercase with a corresponding uppercase code point in 1164 * PT154. 1165 */ 1166 ATF_REQUIRE(setlocale(LC_CTYPE, "kk_KZ.PT154") != NULL); 1167 ATF_CHECK(isalpha(ya)); 1168 ATF_CHECK(!isupper(ya)); 1169 ATF_CHECK(islower(ya)); 1170 ATF_CHECK(!isdigit(ya)); 1171 ATF_CHECK(!isxdigit(ya)); 1172 ATF_CHECK(isalnum(ya)); 1173 ATF_CHECK(!isspace(ya)); 1174 ATF_CHECK(!ispunct(ya)); 1175 ATF_CHECK(isprint(ya)); 1176 ATF_CHECK(isgraph(ya)); 1177 ATF_CHECK(!iscntrl(ya)); 1178 ATF_CHECK(!isblank(ya)); 1179 ATF_CHECK_MSG((ch = toupper(ya)) == Ya, "ch=0x%x", ch); 1180 ATF_CHECK_MSG((ch = tolower(ya)) == ya, "ch=0x%x", ch); 1181 } 1182 1183 ATF_TP_ADD_TCS(tp) 1184 { 1185 1186 ADD_TEST_ABUSE(tp, isalpha); 1187 ADD_TEST_ABUSE(tp, isupper); 1188 ADD_TEST_ABUSE(tp, islower); 1189 ADD_TEST_ABUSE(tp, isdigit); 1190 ADD_TEST_ABUSE(tp, isxdigit); 1191 ADD_TEST_ABUSE(tp, isalnum); 1192 ADD_TEST_ABUSE(tp, isspace); 1193 ADD_TEST_ABUSE(tp, ispunct); 1194 ADD_TEST_ABUSE(tp, isprint); 1195 ADD_TEST_ABUSE(tp, isgraph); 1196 ADD_TEST_ABUSE(tp, iscntrl); 1197 ADD_TEST_ABUSE(tp, isblank); 1198 ADD_TEST_ABUSE(tp, toupper); 1199 ADD_TEST_ABUSE(tp, tolower); 1200 1201 ADD_TEST_ABUSE_OVERRIDE(tp, isalpha); 1202 ADD_TEST_ABUSE_OVERRIDE(tp, isupper); 1203 ADD_TEST_ABUSE_OVERRIDE(tp, islower); 1204 ADD_TEST_ABUSE_OVERRIDE(tp, isdigit); 1205 ADD_TEST_ABUSE_OVERRIDE(tp, isxdigit); 1206 ADD_TEST_ABUSE_OVERRIDE(tp, isalnum); 1207 ADD_TEST_ABUSE_OVERRIDE(tp, isspace); 1208 ADD_TEST_ABUSE_OVERRIDE(tp, ispunct); 1209 ADD_TEST_ABUSE_OVERRIDE(tp, isprint); 1210 ADD_TEST_ABUSE_OVERRIDE(tp, isgraph); 1211 ADD_TEST_ABUSE_OVERRIDE(tp, iscntrl); 1212 ADD_TEST_ABUSE_OVERRIDE(tp, isblank); 1213 ADD_TEST_ABUSE_OVERRIDE(tp, toupper); 1214 ADD_TEST_ABUSE_OVERRIDE(tp, tolower); 1215 1216 ADD_TEST_USE(tp, isalpha); 1217 ADD_TEST_USE(tp, isupper); 1218 ADD_TEST_USE(tp, islower); 1219 ADD_TEST_USE(tp, isdigit); 1220 ADD_TEST_USE(tp, isxdigit); 1221 ADD_TEST_USE(tp, isalnum); 1222 ADD_TEST_USE(tp, isspace); 1223 ADD_TEST_USE(tp, ispunct); 1224 ADD_TEST_USE(tp, isprint); 1225 ADD_TEST_USE(tp, isgraph); 1226 ADD_TEST_USE(tp, iscntrl); 1227 ADD_TEST_USE(tp, isblank); 1228 ADD_TEST_USE(tp, toupper); 1229 ADD_TEST_USE(tp, tolower); 1230 1231 ATF_TP_ADD_TC(tp, eof_confusion_iso8859_1); 1232 ATF_TP_ADD_TC(tp, eof_confusion_koi8_u); 1233 ATF_TP_ADD_TC(tp, eof_confusion_pt154); 1234 1235 return atf_no_error(); 1236 } 1237