1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include <gtest/gtest.h> 18 19 #include <errno.h> 20 #include <fcntl.h> 21 #include <limits.h> 22 #include <math.h> 23 #include <stdio.h> 24 #include <sys/types.h> 25 #include <sys/stat.h> 26 #include <unistd.h> 27 #include <wchar.h> 28 #include <locale.h> 29 30 #include <string> 31 #include <vector> 32 33 #include "BionicDeathTest.h" 34 #include "TemporaryFile.h" 35 #include "utils.h" 36 37 #if defined(NOFORTIFY) 38 #define STDIO_TEST stdio_nofortify 39 #define STDIO_DEATHTEST stdio_nofortify_DeathTest 40 #else 41 #define STDIO_TEST stdio 42 #define STDIO_DEATHTEST stdio_DeathTest 43 #endif 44 45 using namespace std::string_literals; 46 47 class stdio_DeathTest : public BionicDeathTest {}; 48 class stdio_nofortify_DeathTest : public BionicDeathTest {}; 49 50 static void SetFileTo(const char* path, const char* content) { 51 FILE* fp; 52 ASSERT_NE(nullptr, fp = fopen(path, "w")); 53 ASSERT_NE(EOF, fputs(content, fp)); 54 ASSERT_EQ(0, fclose(fp)); 55 } 56 57 static void AssertFileIs(const char* path, const char* expected) { 58 FILE* fp; 59 ASSERT_NE(nullptr, fp = fopen(path, "r")); 60 char* line = nullptr; 61 size_t length; 62 ASSERT_NE(EOF, getline(&line, &length, fp)); 63 ASSERT_EQ(0, fclose(fp)); 64 ASSERT_STREQ(expected, line); 65 free(line); 66 } 67 68 static void AssertFileIs(FILE* fp, const char* expected, bool is_fmemopen = false) { 69 rewind(fp); 70 71 char line[1024]; 72 memset(line, 0xff, sizeof(line)); 73 ASSERT_EQ(line, fgets(line, sizeof(line), fp)); 74 ASSERT_STREQ(expected, line); 75 76 if (is_fmemopen) { 77 // fmemopen appends a trailing NUL byte, which probably shouldn't show up as an 78 // extra empty line, but does on every C library I tested... 79 ASSERT_EQ(line, fgets(line, sizeof(line), fp)); 80 ASSERT_STREQ("", line); 81 } 82 83 // Make sure there isn't anything else in the file. 84 ASSERT_EQ(nullptr, fgets(line, sizeof(line), fp)) << "junk at end of file: " << line; 85 } 86 87 TEST(STDIO_TEST, flockfile_18208568_stderr) { 88 // Check that we have a _recursive_ mutex for flockfile. 89 flockfile(stderr); 90 feof(stderr); // We don't care about the result, but this needs to take the lock. 91 funlockfile(stderr); 92 } 93 94 TEST(STDIO_TEST, flockfile_18208568_regular) { 95 // We never had a bug for streams other than stdin/stdout/stderr, but test anyway. 96 FILE* fp = fopen("/dev/null", "w"); 97 ASSERT_TRUE(fp != NULL); 98 flockfile(fp); 99 feof(fp); 100 funlockfile(fp); 101 fclose(fp); 102 } 103 104 TEST(STDIO_TEST, tmpfile_fileno_fprintf_rewind_fgets) { 105 FILE* fp = tmpfile(); 106 ASSERT_TRUE(fp != NULL); 107 108 int fd = fileno(fp); 109 ASSERT_NE(fd, -1); 110 111 struct stat sb; 112 int rc = fstat(fd, &sb); 113 ASSERT_NE(rc, -1); 114 ASSERT_EQ(sb.st_mode & 0777, 0600U); 115 116 rc = fprintf(fp, "hello\n"); 117 ASSERT_EQ(rc, 6); 118 119 AssertFileIs(fp, "hello\n"); 120 fclose(fp); 121 } 122 123 TEST(STDIO_TEST, tmpfile64) { 124 FILE* fp = tmpfile64(); 125 ASSERT_TRUE(fp != nullptr); 126 fclose(fp); 127 } 128 129 TEST(STDIO_TEST, dprintf) { 130 TemporaryFile tf; 131 132 int rc = dprintf(tf.fd, "hello\n"); 133 ASSERT_EQ(rc, 6); 134 135 lseek(tf.fd, 0, SEEK_SET); 136 FILE* tfile = fdopen(tf.fd, "r"); 137 ASSERT_TRUE(tfile != NULL); 138 139 AssertFileIs(tfile, "hello\n"); 140 fclose(tfile); 141 } 142 143 TEST(STDIO_TEST, getdelim) { 144 FILE* fp = tmpfile(); 145 ASSERT_TRUE(fp != NULL); 146 147 const char* line_written = "This is a test"; 148 int rc = fprintf(fp, "%s", line_written); 149 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 150 151 rewind(fp); 152 153 char* word_read = NULL; 154 size_t allocated_length = 0; 155 156 const char* expected[] = { "This ", " ", "is ", "a ", "test" }; 157 for (size_t i = 0; i < 5; ++i) { 158 ASSERT_FALSE(feof(fp)); 159 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i]))); 160 ASSERT_GE(allocated_length, strlen(expected[i])); 161 ASSERT_STREQ(expected[i], word_read); 162 } 163 // The last read should have set the end-of-file indicator for the stream. 164 ASSERT_TRUE(feof(fp)); 165 clearerr(fp); 166 167 // getdelim returns -1 but doesn't set errno if we're already at EOF. 168 // It should set the end-of-file indicator for the stream, though. 169 errno = 0; 170 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1); 171 ASSERT_EQ(0, errno); 172 ASSERT_TRUE(feof(fp)); 173 174 free(word_read); 175 fclose(fp); 176 } 177 178 TEST(STDIO_TEST, getdelim_invalid) { 179 FILE* fp = tmpfile(); 180 ASSERT_TRUE(fp != NULL); 181 182 char* buffer = NULL; 183 size_t buffer_length = 0; 184 185 // The first argument can't be NULL. 186 errno = 0; 187 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1); 188 ASSERT_EQ(EINVAL, errno); 189 190 // The second argument can't be NULL. 191 errno = 0; 192 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1); 193 ASSERT_EQ(EINVAL, errno); 194 195 // The underlying fd can't be closed. 196 ASSERT_EQ(0, close(fileno(fp))); 197 errno = 0; 198 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1); 199 ASSERT_EQ(EBADF, errno); 200 fclose(fp); 201 } 202 203 TEST(STDIO_TEST, getdelim_directory) { 204 FILE* fp = fopen("/proc", "r"); 205 ASSERT_TRUE(fp != NULL); 206 char* word_read; 207 size_t allocated_length; 208 ASSERT_EQ(-1, getdelim(&word_read, &allocated_length, ' ', fp)); 209 fclose(fp); 210 } 211 212 TEST(STDIO_TEST, getline) { 213 FILE* fp = tmpfile(); 214 ASSERT_TRUE(fp != NULL); 215 216 const char* line_written = "This is a test for getline\n"; 217 const size_t line_count = 5; 218 219 for (size_t i = 0; i < line_count; ++i) { 220 int rc = fprintf(fp, "%s", line_written); 221 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 222 } 223 224 rewind(fp); 225 226 char* line_read = NULL; 227 size_t allocated_length = 0; 228 229 size_t read_line_count = 0; 230 ssize_t read_char_count; 231 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) { 232 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written))); 233 ASSERT_GE(allocated_length, strlen(line_written)); 234 ASSERT_STREQ(line_written, line_read); 235 ++read_line_count; 236 } 237 ASSERT_EQ(read_line_count, line_count); 238 239 // The last read should have set the end-of-file indicator for the stream. 240 ASSERT_TRUE(feof(fp)); 241 clearerr(fp); 242 243 // getline returns -1 but doesn't set errno if we're already at EOF. 244 // It should set the end-of-file indicator for the stream, though. 245 errno = 0; 246 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1); 247 ASSERT_EQ(0, errno); 248 ASSERT_TRUE(feof(fp)); 249 250 free(line_read); 251 fclose(fp); 252 } 253 254 TEST(STDIO_TEST, getline_invalid) { 255 FILE* fp = tmpfile(); 256 ASSERT_TRUE(fp != NULL); 257 258 char* buffer = NULL; 259 size_t buffer_length = 0; 260 261 // The first argument can't be NULL. 262 errno = 0; 263 ASSERT_EQ(getline(NULL, &buffer_length, fp), -1); 264 ASSERT_EQ(EINVAL, errno); 265 266 // The second argument can't be NULL. 267 errno = 0; 268 ASSERT_EQ(getline(&buffer, NULL, fp), -1); 269 ASSERT_EQ(EINVAL, errno); 270 271 // The underlying fd can't be closed. 272 ASSERT_EQ(0, close(fileno(fp))); 273 errno = 0; 274 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1); 275 ASSERT_EQ(EBADF, errno); 276 fclose(fp); 277 } 278 279 TEST(STDIO_TEST, printf_ssize_t) { 280 // http://b/8253769 281 ASSERT_EQ(sizeof(ssize_t), sizeof(long int)); 282 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t)); 283 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying: 284 // error: format '%zd' expects argument of type 'signed size_t', 285 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format] 286 ssize_t v = 1; 287 char buf[32]; 288 snprintf(buf, sizeof(buf), "%zd", v); 289 } 290 291 // https://code.google.com/p/android/issues/detail?id=64886 292 TEST(STDIO_TEST, snprintf_a) { 293 char buf[BUFSIZ]; 294 EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235)); 295 EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf); 296 } 297 298 TEST(STDIO_TEST, snprintf_lc) { 299 char buf[BUFSIZ]; 300 wint_t wc = L'a'; 301 EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc)); 302 EXPECT_STREQ("<a>", buf); 303 } 304 305 TEST(STDIO_TEST, snprintf_C) { // Synonym for %lc. 306 char buf[BUFSIZ]; 307 wchar_t wc = L'a'; 308 EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%C>", wc)); 309 EXPECT_STREQ("<a>", buf); 310 } 311 312 TEST(STDIO_TEST, snprintf_ls) { 313 char buf[BUFSIZ]; 314 wchar_t* ws = NULL; 315 EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws)); 316 EXPECT_STREQ("<(null)>", buf); 317 318 wchar_t chars[] = { L'h', L'i', 0 }; 319 ws = chars; 320 EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws)); 321 EXPECT_STREQ("<hi>", buf); 322 } 323 324 TEST(STDIO_TEST, snprintf_S) { // Synonym for %ls. 325 char buf[BUFSIZ]; 326 wchar_t* ws = NULL; 327 EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%S>", ws)); 328 EXPECT_STREQ("<(null)>", buf); 329 330 wchar_t chars[] = { L'h', L'i', 0 }; 331 ws = chars; 332 EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%S>", ws)); 333 EXPECT_STREQ("<hi>", buf); 334 } 335 336 TEST(STDIO_TEST, snprintf_n) { 337 #if defined(__BIONIC__) 338 // http://b/14492135 339 char buf[32]; 340 int i = 1234; 341 EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i)); 342 EXPECT_EQ(1234, i); 343 EXPECT_STREQ("a n b", buf); 344 #else 345 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n"; 346 #endif 347 } 348 349 TEST(STDIO_TEST, snprintf_smoke) { 350 char buf[BUFSIZ]; 351 352 snprintf(buf, sizeof(buf), "a"); 353 EXPECT_STREQ("a", buf); 354 355 snprintf(buf, sizeof(buf), "%%"); 356 EXPECT_STREQ("%", buf); 357 358 snprintf(buf, sizeof(buf), "01234"); 359 EXPECT_STREQ("01234", buf); 360 361 snprintf(buf, sizeof(buf), "a%sb", "01234"); 362 EXPECT_STREQ("a01234b", buf); 363 364 char* s = NULL; 365 snprintf(buf, sizeof(buf), "a%sb", s); 366 EXPECT_STREQ("a(null)b", buf); 367 368 snprintf(buf, sizeof(buf), "aa%scc", "bb"); 369 EXPECT_STREQ("aabbcc", buf); 370 371 snprintf(buf, sizeof(buf), "a%cc", 'b'); 372 EXPECT_STREQ("abc", buf); 373 374 snprintf(buf, sizeof(buf), "a%db", 1234); 375 EXPECT_STREQ("a1234b", buf); 376 377 snprintf(buf, sizeof(buf), "a%db", -8123); 378 EXPECT_STREQ("a-8123b", buf); 379 380 snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010)); 381 EXPECT_STREQ("a16b", buf); 382 383 snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10)); 384 EXPECT_STREQ("a16b", buf); 385 386 snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL); 387 EXPECT_STREQ("a68719476736b", buf); 388 389 snprintf(buf, sizeof(buf), "a%ldb", 70000L); 390 EXPECT_STREQ("a70000b", buf); 391 392 snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234)); 393 EXPECT_STREQ("a0xb0001234b", buf); 394 395 snprintf(buf, sizeof(buf), "a%xz", 0x12ab); 396 EXPECT_STREQ("a12abz", buf); 397 398 snprintf(buf, sizeof(buf), "a%Xz", 0x12ab); 399 EXPECT_STREQ("a12ABz", buf); 400 401 snprintf(buf, sizeof(buf), "a%08xz", 0x123456); 402 EXPECT_STREQ("a00123456z", buf); 403 404 snprintf(buf, sizeof(buf), "a%5dz", 1234); 405 EXPECT_STREQ("a 1234z", buf); 406 407 snprintf(buf, sizeof(buf), "a%05dz", 1234); 408 EXPECT_STREQ("a01234z", buf); 409 410 snprintf(buf, sizeof(buf), "a%8dz", 1234); 411 EXPECT_STREQ("a 1234z", buf); 412 413 snprintf(buf, sizeof(buf), "a%-8dz", 1234); 414 EXPECT_STREQ("a1234 z", buf); 415 416 snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef"); 417 EXPECT_STREQ("Aabcdef Z", buf); 418 419 snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234); 420 EXPECT_STREQ("Ahello:1234Z", buf); 421 422 snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5); 423 EXPECT_STREQ("a005:5:05z", buf); 424 425 void* p = NULL; 426 snprintf(buf, sizeof(buf), "a%d,%pz", 5, p); 427 #if defined(__BIONIC__) 428 EXPECT_STREQ("a5,0x0z", buf); 429 #else // __BIONIC__ 430 EXPECT_STREQ("a5,(nil)z", buf); 431 #endif // __BIONIC__ 432 433 snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8); 434 EXPECT_STREQ("a68719476736,6,7,8z", buf); 435 436 snprintf(buf, sizeof(buf), "a_%f_b", 1.23f); 437 EXPECT_STREQ("a_1.230000_b", buf); 438 439 snprintf(buf, sizeof(buf), "a_%g_b", 3.14); 440 EXPECT_STREQ("a_3.14_b", buf); 441 442 snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice"); 443 EXPECT_STREQ("print_me_twice print_me_twice", buf); 444 } 445 446 template <typename T> 447 static void CheckInfNan(int snprintf_fn(T*, size_t, const T*, ...), 448 int sscanf_fn(const T*, const T*, ...), 449 const T* fmt_string, const T* fmt, const T* fmt_plus, 450 const T* minus_inf, const T* inf_, const T* plus_inf, 451 const T* minus_nan, const T* nan_, const T* plus_nan) { 452 T buf[BUFSIZ]; 453 float f; 454 455 // NaN. 456 457 snprintf_fn(buf, sizeof(buf), fmt, nanf("")); 458 EXPECT_STREQ(nan_, buf) << fmt; 459 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 460 EXPECT_TRUE(isnan(f)); 461 462 snprintf_fn(buf, sizeof(buf), fmt, -nanf("")); 463 EXPECT_STREQ(minus_nan, buf) << fmt; 464 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 465 EXPECT_TRUE(isnan(f)); 466 467 snprintf_fn(buf, sizeof(buf), fmt_plus, nanf("")); 468 EXPECT_STREQ(plus_nan, buf) << fmt_plus; 469 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 470 EXPECT_TRUE(isnan(f)); 471 472 snprintf_fn(buf, sizeof(buf), fmt_plus, -nanf("")); 473 EXPECT_STREQ(minus_nan, buf) << fmt_plus; 474 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 475 EXPECT_TRUE(isnan(f)); 476 477 // Inf. 478 479 snprintf_fn(buf, sizeof(buf), fmt, HUGE_VALF); 480 EXPECT_STREQ(inf_, buf) << fmt; 481 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 482 EXPECT_EQ(HUGE_VALF, f); 483 484 snprintf_fn(buf, sizeof(buf), fmt, -HUGE_VALF); 485 EXPECT_STREQ(minus_inf, buf) << fmt; 486 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 487 EXPECT_EQ(-HUGE_VALF, f); 488 489 snprintf_fn(buf, sizeof(buf), fmt_plus, HUGE_VALF); 490 EXPECT_STREQ(plus_inf, buf) << fmt_plus; 491 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 492 EXPECT_EQ(HUGE_VALF, f); 493 494 snprintf_fn(buf, sizeof(buf), fmt_plus, -HUGE_VALF); 495 EXPECT_STREQ(minus_inf, buf) << fmt_plus; 496 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 497 EXPECT_EQ(-HUGE_VALF, f); 498 499 // Check case-insensitivity. 500 snprintf_fn(buf, sizeof(buf), fmt_string, "[InFiNiTy]"); 501 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)) << buf; 502 EXPECT_EQ(HUGE_VALF, f); 503 snprintf_fn(buf, sizeof(buf), fmt_string, "[NaN]"); 504 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)) << buf; 505 EXPECT_TRUE(isnan(f)); 506 } 507 508 TEST(STDIO_TEST, snprintf_sscanf_inf_nan) { 509 CheckInfNan(snprintf, sscanf, "%s", 510 "[%a]", "[%+a]", 511 "[-inf]", "[inf]", "[+inf]", 512 "[-nan]", "[nan]", "[+nan]"); 513 CheckInfNan(snprintf, sscanf, "%s", 514 "[%A]", "[%+A]", 515 "[-INF]", "[INF]", "[+INF]", 516 "[-NAN]", "[NAN]", "[+NAN]"); 517 CheckInfNan(snprintf, sscanf, "%s", 518 "[%e]", "[%+e]", 519 "[-inf]", "[inf]", "[+inf]", 520 "[-nan]", "[nan]", "[+nan]"); 521 CheckInfNan(snprintf, sscanf, "%s", 522 "[%E]", "[%+E]", 523 "[-INF]", "[INF]", "[+INF]", 524 "[-NAN]", "[NAN]", "[+NAN]"); 525 CheckInfNan(snprintf, sscanf, "%s", 526 "[%f]", "[%+f]", 527 "[-inf]", "[inf]", "[+inf]", 528 "[-nan]", "[nan]", "[+nan]"); 529 CheckInfNan(snprintf, sscanf, "%s", 530 "[%F]", "[%+F]", 531 "[-INF]", "[INF]", "[+INF]", 532 "[-NAN]", "[NAN]", "[+NAN]"); 533 CheckInfNan(snprintf, sscanf, "%s", 534 "[%g]", "[%+g]", 535 "[-inf]", "[inf]", "[+inf]", 536 "[-nan]", "[nan]", "[+nan]"); 537 CheckInfNan(snprintf, sscanf, "%s", 538 "[%G]", "[%+G]", 539 "[-INF]", "[INF]", "[+INF]", 540 "[-NAN]", "[NAN]", "[+NAN]"); 541 } 542 543 TEST(STDIO_TEST, swprintf_swscanf_inf_nan) { 544 CheckInfNan(swprintf, swscanf, L"%s", 545 L"[%a]", L"[%+a]", 546 L"[-inf]", L"[inf]", L"[+inf]", 547 L"[-nan]", L"[nan]", L"[+nan]"); 548 CheckInfNan(swprintf, swscanf, L"%s", 549 L"[%A]", L"[%+A]", 550 L"[-INF]", L"[INF]", L"[+INF]", 551 L"[-NAN]", L"[NAN]", L"[+NAN]"); 552 CheckInfNan(swprintf, swscanf, L"%s", 553 L"[%e]", L"[%+e]", 554 L"[-inf]", L"[inf]", L"[+inf]", 555 L"[-nan]", L"[nan]", L"[+nan]"); 556 CheckInfNan(swprintf, swscanf, L"%s", 557 L"[%E]", L"[%+E]", 558 L"[-INF]", L"[INF]", L"[+INF]", 559 L"[-NAN]", L"[NAN]", L"[+NAN]"); 560 CheckInfNan(swprintf, swscanf, L"%s", 561 L"[%f]", L"[%+f]", 562 L"[-inf]", L"[inf]", L"[+inf]", 563 L"[-nan]", L"[nan]", L"[+nan]"); 564 CheckInfNan(swprintf, swscanf, L"%s", 565 L"[%F]", L"[%+F]", 566 L"[-INF]", L"[INF]", L"[+INF]", 567 L"[-NAN]", L"[NAN]", L"[+NAN]"); 568 CheckInfNan(swprintf, swscanf, L"%s", 569 L"[%g]", L"[%+g]", 570 L"[-inf]", L"[inf]", L"[+inf]", 571 L"[-nan]", L"[nan]", L"[+nan]"); 572 CheckInfNan(swprintf, swscanf, L"%s", 573 L"[%G]", L"[%+G]", 574 L"[-INF]", L"[INF]", L"[+INF]", 575 L"[-NAN]", L"[NAN]", L"[+NAN]"); 576 } 577 578 TEST(STDIO_TEST, swprintf) { 579 constexpr size_t nchars = 32; 580 wchar_t buf[nchars]; 581 582 ASSERT_EQ(2, swprintf(buf, nchars, L"ab")) << strerror(errno); 583 ASSERT_EQ(std::wstring(L"ab"), buf); 584 ASSERT_EQ(5, swprintf(buf, nchars, L"%s", "abcde")); 585 ASSERT_EQ(std::wstring(L"abcde"), buf); 586 587 // Unlike swprintf(), swprintf() returns -1 in case of truncation 588 // and doesn't necessarily zero-terminate the output! 589 ASSERT_EQ(-1, swprintf(buf, 4, L"%s", "abcde")); 590 591 const char kString[] = "Hello, World"; 592 ASSERT_EQ(12, swprintf(buf, nchars, L"%s", kString)); 593 ASSERT_EQ(std::wstring(L"Hello, World"), buf); 594 ASSERT_EQ(12, swprintf(buf, 13, L"%s", kString)); 595 ASSERT_EQ(std::wstring(L"Hello, World"), buf); 596 } 597 598 TEST(STDIO_TEST, swprintf_a) { 599 constexpr size_t nchars = 32; 600 wchar_t buf[nchars]; 601 602 ASSERT_EQ(20, swprintf(buf, nchars, L"%a", 3.1415926535)); 603 ASSERT_EQ(std::wstring(L"0x1.921fb54411744p+1"), buf); 604 } 605 606 TEST(STDIO_TEST, swprintf_lc) { 607 constexpr size_t nchars = 32; 608 wchar_t buf[nchars]; 609 610 wint_t wc = L'a'; 611 EXPECT_EQ(3, swprintf(buf, nchars, L"<%lc>", wc)); 612 EXPECT_EQ(std::wstring(L"<a>"), buf); 613 } 614 615 TEST(STDIO_TEST, swprintf_C) { // Synonym for %lc. 616 constexpr size_t nchars = 32; 617 wchar_t buf[nchars]; 618 619 wint_t wc = L'a'; 620 EXPECT_EQ(3, swprintf(buf, nchars, L"<%C>", wc)); 621 EXPECT_EQ(std::wstring(L"<a>"), buf); 622 } 623 624 TEST(STDIO_TEST, swprintf_jd_INTMAX_MAX) { 625 constexpr size_t nchars = 32; 626 wchar_t buf[nchars]; 627 628 swprintf(buf, nchars, L"%jd", INTMAX_MAX); 629 EXPECT_EQ(std::wstring(L"9223372036854775807"), buf); 630 } 631 632 TEST(STDIO_TEST, swprintf_jd_INTMAX_MIN) { 633 constexpr size_t nchars = 32; 634 wchar_t buf[nchars]; 635 636 swprintf(buf, nchars, L"%jd", INTMAX_MIN); 637 EXPECT_EQ(std::wstring(L"-9223372036854775808"), buf); 638 } 639 640 TEST(STDIO_TEST, swprintf_ju_UINTMAX_MAX) { 641 constexpr size_t nchars = 32; 642 wchar_t buf[nchars]; 643 644 swprintf(buf, nchars, L"%ju", UINTMAX_MAX); 645 EXPECT_EQ(std::wstring(L"18446744073709551615"), buf); 646 } 647 648 TEST(STDIO_TEST, swprintf_1$ju_UINTMAX_MAX) { 649 constexpr size_t nchars = 32; 650 wchar_t buf[nchars]; 651 652 swprintf(buf, nchars, L"%1$ju", UINTMAX_MAX); 653 EXPECT_EQ(std::wstring(L"18446744073709551615"), buf); 654 } 655 656 TEST(STDIO_TEST, swprintf_ls) { 657 constexpr size_t nchars = 32; 658 wchar_t buf[nchars]; 659 660 static const wchar_t kWideString[] = L"Hello\uff41 World"; 661 ASSERT_EQ(12, swprintf(buf, nchars, L"%ls", kWideString)); 662 ASSERT_EQ(std::wstring(kWideString), buf); 663 ASSERT_EQ(12, swprintf(buf, 13, L"%ls", kWideString)); 664 ASSERT_EQ(std::wstring(kWideString), buf); 665 } 666 667 TEST(STDIO_TEST, swprintf_S) { // Synonym for %ls. 668 constexpr size_t nchars = 32; 669 wchar_t buf[nchars]; 670 671 static const wchar_t kWideString[] = L"Hello\uff41 World"; 672 ASSERT_EQ(12, swprintf(buf, nchars, L"%S", kWideString)); 673 ASSERT_EQ(std::wstring(kWideString), buf); 674 ASSERT_EQ(12, swprintf(buf, 13, L"%S", kWideString)); 675 ASSERT_EQ(std::wstring(kWideString), buf); 676 } 677 678 TEST(STDIO_TEST, snprintf_d_INT_MAX) { 679 char buf[BUFSIZ]; 680 snprintf(buf, sizeof(buf), "%d", INT_MAX); 681 EXPECT_STREQ("2147483647", buf); 682 } 683 684 TEST(STDIO_TEST, snprintf_d_INT_MIN) { 685 char buf[BUFSIZ]; 686 snprintf(buf, sizeof(buf), "%d", INT_MIN); 687 EXPECT_STREQ("-2147483648", buf); 688 } 689 690 TEST(STDIO_TEST, snprintf_jd_INTMAX_MAX) { 691 char buf[BUFSIZ]; 692 snprintf(buf, sizeof(buf), "%jd", INTMAX_MAX); 693 EXPECT_STREQ("9223372036854775807", buf); 694 } 695 696 TEST(STDIO_TEST, snprintf_jd_INTMAX_MIN) { 697 char buf[BUFSIZ]; 698 snprintf(buf, sizeof(buf), "%jd", INTMAX_MIN); 699 EXPECT_STREQ("-9223372036854775808", buf); 700 } 701 702 TEST(STDIO_TEST, snprintf_ju_UINTMAX_MAX) { 703 char buf[BUFSIZ]; 704 snprintf(buf, sizeof(buf), "%ju", UINTMAX_MAX); 705 EXPECT_STREQ("18446744073709551615", buf); 706 } 707 708 TEST(STDIO_TEST, snprintf_1$ju_UINTMAX_MAX) { 709 char buf[BUFSIZ]; 710 snprintf(buf, sizeof(buf), "%1$ju", UINTMAX_MAX); 711 EXPECT_STREQ("18446744073709551615", buf); 712 } 713 714 TEST(STDIO_TEST, snprintf_ld_LONG_MAX) { 715 char buf[BUFSIZ]; 716 snprintf(buf, sizeof(buf), "%ld", LONG_MAX); 717 #if defined(__LP64__) 718 EXPECT_STREQ("9223372036854775807", buf); 719 #else 720 EXPECT_STREQ("2147483647", buf); 721 #endif 722 } 723 724 TEST(STDIO_TEST, snprintf_ld_LONG_MIN) { 725 char buf[BUFSIZ]; 726 snprintf(buf, sizeof(buf), "%ld", LONG_MIN); 727 #if defined(__LP64__) 728 EXPECT_STREQ("-9223372036854775808", buf); 729 #else 730 EXPECT_STREQ("-2147483648", buf); 731 #endif 732 } 733 734 TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) { 735 char buf[BUFSIZ]; 736 snprintf(buf, sizeof(buf), "%lld", LLONG_MAX); 737 EXPECT_STREQ("9223372036854775807", buf); 738 } 739 740 TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) { 741 char buf[BUFSIZ]; 742 snprintf(buf, sizeof(buf), "%lld", LLONG_MIN); 743 EXPECT_STREQ("-9223372036854775808", buf); 744 } 745 746 TEST(STDIO_TEST, snprintf_o_UINT_MAX) { 747 char buf[BUFSIZ]; 748 snprintf(buf, sizeof(buf), "%o", UINT_MAX); 749 EXPECT_STREQ("37777777777", buf); 750 } 751 752 TEST(STDIO_TEST, snprintf_u_UINT_MAX) { 753 char buf[BUFSIZ]; 754 snprintf(buf, sizeof(buf), "%u", UINT_MAX); 755 EXPECT_STREQ("4294967295", buf); 756 } 757 758 TEST(STDIO_TEST, snprintf_x_UINT_MAX) { 759 char buf[BUFSIZ]; 760 snprintf(buf, sizeof(buf), "%x", UINT_MAX); 761 EXPECT_STREQ("ffffffff", buf); 762 } 763 764 TEST(STDIO_TEST, snprintf_X_UINT_MAX) { 765 char buf[BUFSIZ]; 766 snprintf(buf, sizeof(buf), "%X", UINT_MAX); 767 EXPECT_STREQ("FFFFFFFF", buf); 768 } 769 770 TEST(STDIO_TEST, snprintf_e) { 771 char buf[BUFSIZ]; 772 773 snprintf(buf, sizeof(buf), "%e", 1.5); 774 EXPECT_STREQ("1.500000e+00", buf); 775 776 snprintf(buf, sizeof(buf), "%Le", 1.5l); 777 EXPECT_STREQ("1.500000e+00", buf); 778 } 779 780 TEST(STDIO_TEST, snprintf_negative_zero_5084292) { 781 char buf[BUFSIZ]; 782 783 snprintf(buf, sizeof(buf), "%e", -0.0); 784 EXPECT_STREQ("-0.000000e+00", buf); 785 snprintf(buf, sizeof(buf), "%E", -0.0); 786 EXPECT_STREQ("-0.000000E+00", buf); 787 snprintf(buf, sizeof(buf), "%f", -0.0); 788 EXPECT_STREQ("-0.000000", buf); 789 snprintf(buf, sizeof(buf), "%F", -0.0); 790 EXPECT_STREQ("-0.000000", buf); 791 snprintf(buf, sizeof(buf), "%g", -0.0); 792 EXPECT_STREQ("-0", buf); 793 snprintf(buf, sizeof(buf), "%G", -0.0); 794 EXPECT_STREQ("-0", buf); 795 snprintf(buf, sizeof(buf), "%a", -0.0); 796 EXPECT_STREQ("-0x0p+0", buf); 797 snprintf(buf, sizeof(buf), "%A", -0.0); 798 EXPECT_STREQ("-0X0P+0", buf); 799 } 800 801 TEST(STDIO_TEST, snprintf_utf8_15439554) { 802 locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0); 803 locale_t old_locale = uselocale(cloc); 804 805 // http://b/15439554 806 char buf[BUFSIZ]; 807 808 // 1-byte character. 809 snprintf(buf, sizeof(buf), "%dx%d", 1, 2); 810 EXPECT_STREQ("1x2", buf); 811 // 2-byte character. 812 snprintf(buf, sizeof(buf), "%d\xc2\xa2%d", 1, 2); 813 EXPECT_STREQ("12", buf); 814 // 3-byte character. 815 snprintf(buf, sizeof(buf), "%d\xe2\x82\xac%d", 1, 2); 816 EXPECT_STREQ("12", buf); 817 // 4-byte character. 818 snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2); 819 EXPECT_STREQ("12", buf); 820 821 uselocale(old_locale); 822 freelocale(cloc); 823 } 824 825 static void* snprintf_small_stack_fn(void*) { 826 // Make life (realistically) hard for ourselves by allocating our own buffer for the result. 827 char buf[PATH_MAX]; 828 snprintf(buf, sizeof(buf), "/proc/%d", getpid()); 829 return nullptr; 830 } 831 832 TEST(STDIO_TEST, snprintf_small_stack) { 833 // Is it safe to call snprintf on a thread with a small stack? 834 // (The snprintf implementation puts some pretty large buffers on the stack.) 835 pthread_attr_t a; 836 ASSERT_EQ(0, pthread_attr_init(&a)); 837 ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN)); 838 839 pthread_t t; 840 ASSERT_EQ(0, pthread_create(&t, &a, snprintf_small_stack_fn, nullptr)); 841 ASSERT_EQ(0, pthread_join(t, nullptr)); 842 } 843 844 TEST(STDIO_TEST, snprintf_asterisk_overflow) { 845 char buf[128]; 846 ASSERT_EQ(5, snprintf(buf, sizeof(buf), "%.*s%c", 4, "hello world", '!')); 847 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX/2, "hello world", '!')); 848 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX-1, "hello world", '!')); 849 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX, "hello world", '!')); 850 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", -1, "hello world", '!')); 851 852 // INT_MAX-1, INT_MAX, INT_MAX+1. 853 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483646s%c", "hello world", '!')); 854 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483647s%c", "hello world", '!')); 855 ASSERT_EQ(-1, snprintf(buf, sizeof(buf), "%.2147483648s%c", "hello world", '!')); 856 ASSERT_EQ(ENOMEM, errno); 857 } 858 859 TEST(STDIO_TEST, fprintf) { 860 TemporaryFile tf; 861 862 FILE* tfile = fdopen(tf.fd, "r+"); 863 ASSERT_TRUE(tfile != nullptr); 864 865 ASSERT_EQ(7, fprintf(tfile, "%d %s", 123, "abc")); 866 AssertFileIs(tfile, "123 abc"); 867 fclose(tfile); 868 } 869 870 TEST(STDIO_TEST, fprintf_failures_7229520) { 871 // http://b/7229520 872 FILE* fp; 873 874 // Unbuffered case where the fprintf(3) itself fails. 875 ASSERT_NE(nullptr, fp = tmpfile()); 876 setbuf(fp, NULL); 877 ASSERT_EQ(4, fprintf(fp, "epic")); 878 ASSERT_EQ(0, close(fileno(fp))); 879 ASSERT_EQ(-1, fprintf(fp, "fail")); 880 ASSERT_EQ(-1, fclose(fp)); 881 882 // Buffered case where we won't notice until the fclose(3). 883 // It's likely this is what was actually seen in http://b/7229520, 884 // and that expecting fprintf to fail is setting yourself up for 885 // disappointment. Remember to check fclose(3)'s return value, kids! 886 ASSERT_NE(nullptr, fp = tmpfile()); 887 ASSERT_EQ(4, fprintf(fp, "epic")); 888 ASSERT_EQ(0, close(fileno(fp))); 889 ASSERT_EQ(4, fprintf(fp, "fail")); 890 ASSERT_EQ(-1, fclose(fp)); 891 } 892 893 TEST(STDIO_TEST, popen) { 894 FILE* fp = popen("cat /proc/version", "r"); 895 ASSERT_TRUE(fp != NULL); 896 897 char buf[16]; 898 char* s = fgets(buf, sizeof(buf), fp); 899 buf[13] = '\0'; 900 ASSERT_STREQ("Linux version", s); 901 902 ASSERT_EQ(0, pclose(fp)); 903 } 904 905 TEST(STDIO_TEST, getc) { 906 FILE* fp = fopen("/proc/version", "r"); 907 ASSERT_TRUE(fp != NULL); 908 ASSERT_EQ('L', getc(fp)); 909 ASSERT_EQ('i', getc(fp)); 910 ASSERT_EQ('n', getc(fp)); 911 ASSERT_EQ('u', getc(fp)); 912 ASSERT_EQ('x', getc(fp)); 913 fclose(fp); 914 } 915 916 TEST(STDIO_TEST, putc) { 917 FILE* fp = fopen("/proc/version", "r"); 918 ASSERT_TRUE(fp != NULL); 919 ASSERT_EQ(EOF, putc('x', fp)); 920 fclose(fp); 921 } 922 923 TEST(STDIO_TEST, sscanf_swscanf) { 924 struct stuff { 925 char s1[123]; 926 int i1, i2; 927 char cs1[3]; 928 char s2[3]; 929 char c1; 930 double d1; 931 float f1; 932 char s3[123]; 933 934 void Check() { 935 EXPECT_STREQ("hello", s1); 936 EXPECT_EQ(123, i1); 937 EXPECT_EQ(456, i2); 938 EXPECT_EQ('a', cs1[0]); 939 EXPECT_EQ('b', cs1[1]); 940 EXPECT_EQ('x', cs1[2]); // No terminating NUL. 941 EXPECT_STREQ("AB", s2); // Terminating NUL. 942 EXPECT_EQ('!', c1); 943 EXPECT_DOUBLE_EQ(1.23, d1); 944 EXPECT_FLOAT_EQ(9.0f, f1); 945 EXPECT_STREQ("world", s3); 946 } 947 } s; 948 949 memset(&s, 'x', sizeof(s)); 950 ASSERT_EQ(9, sscanf(" hello 123 456abAB! 1.23 0x1.2p3 world", 951 "%s %i%i%2c%[A-Z]%c %lf %f %s", 952 s.s1, &s.i1, &s.i2, s.cs1, s.s2, &s.c1, &s.d1, &s.f1, s.s3)); 953 s.Check(); 954 955 memset(&s, 'x', sizeof(s)); 956 ASSERT_EQ(9, swscanf(L" hello 123 456abAB! 1.23 0x1.2p3 world", 957 L"%s %i%i%2c%[A-Z]%c %lf %f %s", 958 s.s1, &s.i1, &s.i2, s.cs1, s.s2, &s.c1, &s.d1, &s.f1, s.s3)); 959 s.Check(); 960 } 961 962 template <typename T> 963 static void CheckScanf(int sscanf_fn(const T*, const T*, ...), 964 const T* input, const T* fmt, 965 int expected_count, const char* expected_string) { 966 char buf[256] = {}; 967 ASSERT_EQ(expected_count, sscanf_fn(input, fmt, &buf)) << fmt; 968 ASSERT_STREQ(expected_string, buf) << fmt; 969 } 970 971 TEST(STDIO_TEST, sscanf_ccl) { 972 // `abc` is just those characters. 973 CheckScanf(sscanf, "abcd", "%[abc]", 1, "abc"); 974 // `a-c` is the range 'a' .. 'c'. 975 CheckScanf(sscanf, "abcd", "%[a-c]", 1, "abc"); 976 CheckScanf(sscanf, "-d", "%[a-c]", 0, ""); 977 CheckScanf(sscanf, "ac-bAd", "%[a--c]", 1, "ac-bA"); 978 // `a-c-e` is equivalent to `a-e`. 979 CheckScanf(sscanf, "abcdefg", "%[a-c-e]", 1, "abcde"); 980 // `e-a` is equivalent to `ae-` (because 'e' > 'a'). 981 CheckScanf(sscanf, "-a-e-b", "%[e-a]", 1, "-a-e-"); 982 // An initial '^' negates the set. 983 CheckScanf(sscanf, "abcde", "%[^d]", 1, "abc"); 984 CheckScanf(sscanf, "abcdefgh", "%[^c-d]", 1, "ab"); 985 CheckScanf(sscanf, "hgfedcba", "%[^c-d]", 1, "hgfe"); 986 // The first character may be ']' or '-' without being special. 987 CheckScanf(sscanf, "[[]]x", "%[][]", 1, "[[]]"); 988 CheckScanf(sscanf, "-a-x", "%[-a]", 1, "-a-"); 989 // The last character may be '-' without being special. 990 CheckScanf(sscanf, "-a-x", "%[a-]", 1, "-a-"); 991 // X--Y is [X--] + Y, not [X--] + [--Y] (a bug in my initial implementation). 992 CheckScanf(sscanf, "+,-/.", "%[+--/]", 1, "+,-/"); 993 } 994 995 TEST(STDIO_TEST, swscanf_ccl) { 996 // `abc` is just those characters. 997 CheckScanf(swscanf, L"abcd", L"%[abc]", 1, "abc"); 998 // `a-c` is the range 'a' .. 'c'. 999 CheckScanf(swscanf, L"abcd", L"%[a-c]", 1, "abc"); 1000 CheckScanf(swscanf, L"-d", L"%[a-c]", 0, ""); 1001 CheckScanf(swscanf, L"ac-bAd", L"%[a--c]", 1, "ac-bA"); 1002 // `a-c-e` is equivalent to `a-e`. 1003 CheckScanf(swscanf, L"abcdefg", L"%[a-c-e]", 1, "abcde"); 1004 // `e-a` is equivalent to `ae-` (because 'e' > 'a'). 1005 CheckScanf(swscanf, L"-a-e-b", L"%[e-a]", 1, "-a-e-"); 1006 // An initial '^' negates the set. 1007 CheckScanf(swscanf, L"abcde", L"%[^d]", 1, "abc"); 1008 CheckScanf(swscanf, L"abcdefgh", L"%[^c-d]", 1, "ab"); 1009 CheckScanf(swscanf, L"hgfedcba", L"%[^c-d]", 1, "hgfe"); 1010 // The first character may be ']' or '-' without being special. 1011 CheckScanf(swscanf, L"[[]]x", L"%[][]", 1, "[[]]"); 1012 CheckScanf(swscanf, L"-a-x", L"%[-a]", 1, "-a-"); 1013 // The last character may be '-' without being special. 1014 CheckScanf(swscanf, L"-a-x", L"%[a-]", 1, "-a-"); 1015 // X--Y is [X--] + Y, not [X--] + [--Y] (a bug in my initial implementation). 1016 CheckScanf(swscanf, L"+,-/.", L"%[+--/]", 1, "+,-/"); 1017 } 1018 1019 template <typename T1, typename T2> 1020 static void CheckScanfM(int sscanf_fn(const T1*, const T1*, ...), 1021 const T1* input, const T1* fmt, 1022 int expected_count, const T2* expected_string) { 1023 T2* result = nullptr; 1024 ASSERT_EQ(expected_count, sscanf_fn(input, fmt, &result)) << fmt; 1025 if (expected_string == nullptr) { 1026 ASSERT_EQ(nullptr, result); 1027 } else { 1028 ASSERT_STREQ(expected_string, result) << fmt; 1029 } 1030 free(result); 1031 } 1032 1033 TEST(STDIO_TEST, sscanf_mc) { 1034 char* p1 = nullptr; 1035 char* p2 = nullptr; 1036 ASSERT_EQ(2, sscanf("hello", "%mc%mc", &p1, &p2)); 1037 ASSERT_EQ('h', *p1); 1038 ASSERT_EQ('e', *p2); 1039 free(p1); 1040 free(p2); 1041 1042 p1 = nullptr; 1043 ASSERT_EQ(1, sscanf("hello", "%4mc", &p1)); 1044 ASSERT_EQ('h', p1[0]); 1045 ASSERT_EQ('e', p1[1]); 1046 ASSERT_EQ('l', p1[2]); 1047 ASSERT_EQ('l', p1[3]); 1048 free(p1); 1049 1050 p1 = nullptr; 1051 ASSERT_EQ(1, sscanf("hello world", "%30mc", &p1)); 1052 ASSERT_EQ('h', p1[0]); 1053 ASSERT_EQ('e', p1[1]); 1054 ASSERT_EQ('l', p1[2]); 1055 ASSERT_EQ('l', p1[3]); 1056 ASSERT_EQ('o', p1[4]); 1057 free(p1); 1058 } 1059 1060 1061 TEST(STDIO_TEST, sscanf_mlc) { 1062 // This is so useless that clang doesn't even believe it exists... 1063 #pragma clang diagnostic push 1064 #pragma clang diagnostic ignored "-Wformat-invalid-specifier" 1065 #pragma clang diagnostic ignored "-Wformat-extra-args" 1066 1067 wchar_t* p1 = nullptr; 1068 wchar_t* p2 = nullptr; 1069 ASSERT_EQ(2, sscanf("hello", "%mlc%mlc", &p1, &p2)); 1070 ASSERT_EQ(L'h', *p1); 1071 ASSERT_EQ(L'e', *p2); 1072 free(p1); 1073 free(p2); 1074 1075 p1 = nullptr; 1076 ASSERT_EQ(1, sscanf("hello", "%4mlc", &p1)); 1077 ASSERT_EQ(L'h', p1[0]); 1078 ASSERT_EQ(L'e', p1[1]); 1079 ASSERT_EQ(L'l', p1[2]); 1080 ASSERT_EQ(L'l', p1[3]); 1081 free(p1); 1082 1083 p1 = nullptr; 1084 ASSERT_EQ(1, sscanf("hello world", "%30mlc", &p1)); 1085 ASSERT_EQ(L'h', p1[0]); 1086 ASSERT_EQ(L'e', p1[1]); 1087 ASSERT_EQ(L'l', p1[2]); 1088 ASSERT_EQ(L'l', p1[3]); 1089 ASSERT_EQ(L'o', p1[4]); 1090 free(p1); 1091 #pragma clang diagnostic pop 1092 } 1093 1094 1095 TEST(STDIO_TEST, sscanf_ms) { 1096 CheckScanfM(sscanf, "hello", "%ms", 1, "hello"); 1097 CheckScanfM(sscanf, "hello", "%4ms", 1, "hell"); 1098 CheckScanfM(sscanf, "hello world", "%30ms", 1, "hello"); 1099 } 1100 1101 TEST(STDIO_TEST, sscanf_mls) { 1102 CheckScanfM(sscanf, "hello", "%mls", 1, L"hello"); 1103 CheckScanfM(sscanf, "hello", "%4mls", 1, L"hell"); 1104 CheckScanfM(sscanf, "hello world", "%30mls", 1, L"hello"); 1105 } 1106 1107 TEST(STDIO_TEST, sscanf_m_ccl) { 1108 CheckScanfM(sscanf, "hello", "%m[a-z]", 1, "hello"); 1109 CheckScanfM(sscanf, "hello", "%4m[a-z]", 1, "hell"); 1110 CheckScanfM(sscanf, "hello world", "%30m[a-z]", 1, "hello"); 1111 } 1112 1113 TEST(STDIO_TEST, sscanf_ml_ccl) { 1114 CheckScanfM(sscanf, "hello", "%ml[a-z]", 1, L"hello"); 1115 CheckScanfM(sscanf, "hello", "%4ml[a-z]", 1, L"hell"); 1116 CheckScanfM(sscanf, "hello world", "%30ml[a-z]", 1, L"hello"); 1117 } 1118 1119 TEST(STDIO_TEST, sscanf_ls) { 1120 wchar_t w[32] = {}; 1121 ASSERT_EQ(1, sscanf("hello world", "%ls", w)); 1122 ASSERT_EQ(L"hello", std::wstring(w)); 1123 } 1124 1125 TEST(STDIO_TEST, sscanf_ls_suppress) { 1126 ASSERT_EQ(0, sscanf("hello world", "%*ls %*ls")); 1127 } 1128 1129 TEST(STDIO_TEST, sscanf_ls_n) { 1130 setlocale(LC_ALL, "C.UTF-8"); 1131 wchar_t w[32] = {}; 1132 int pos = 0; 1133 ASSERT_EQ(1, sscanf("\xc4\x80", "%ls%n", w, &pos)); 1134 ASSERT_EQ(static_cast<wchar_t>(256), w[0]); 1135 ASSERT_EQ(2, pos); 1136 } 1137 1138 TEST(STDIO_TEST, sscanf_ls_realloc) { 1139 // This is so useless that clang doesn't even believe it exists... 1140 #pragma clang diagnostic push 1141 #pragma clang diagnostic ignored "-Wformat-invalid-specifier" 1142 #pragma clang diagnostic ignored "-Wformat-extra-args" 1143 wchar_t* p1 = nullptr; 1144 wchar_t* p2 = nullptr; 1145 ASSERT_EQ(2, sscanf("1234567890123456789012345678901234567890 world", "%mls %mls", &p1, &p2)); 1146 ASSERT_EQ(L"1234567890123456789012345678901234567890", std::wstring(p1)); 1147 ASSERT_EQ(L"world", std::wstring(p2)); 1148 #pragma clang diagnostic pop 1149 } 1150 1151 // https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=202240 1152 TEST(STDIO_TEST, scanf_wscanf_EOF) { 1153 EXPECT_EQ(0, sscanf("b", "ab")); 1154 EXPECT_EQ(EOF, sscanf("", "a")); 1155 EXPECT_EQ(0, swscanf(L"b", L"ab")); 1156 EXPECT_EQ(EOF, swscanf(L"", L"a")); 1157 } 1158 1159 TEST(STDIO_TEST, scanf_invalid_UTF8) { 1160 #if 0 // TODO: more tests invented during code review; no regressions, so fix later. 1161 char buf[BUFSIZ]; 1162 wchar_t wbuf[BUFSIZ]; 1163 1164 memset(buf, 0, sizeof(buf)); 1165 memset(wbuf, 0, sizeof(wbuf)); 1166 EXPECT_EQ(0, sscanf("\xc0" " foo", "%ls %s", wbuf, buf)); 1167 #endif 1168 } 1169 1170 TEST(STDIO_TEST, scanf_no_match_no_termination) { 1171 char buf[4] = "x"; 1172 EXPECT_EQ(0, sscanf("d", "%[abc]", buf)); 1173 EXPECT_EQ('x', buf[0]); 1174 EXPECT_EQ(0, swscanf(L"d", L"%[abc]", buf)); 1175 EXPECT_EQ('x', buf[0]); 1176 1177 wchar_t wbuf[4] = L"x"; 1178 EXPECT_EQ(0, swscanf(L"d", L"%l[abc]", wbuf)); 1179 EXPECT_EQ(L'x', wbuf[0]); 1180 1181 EXPECT_EQ(EOF, sscanf("", "%s", buf)); 1182 EXPECT_EQ('x', buf[0]); 1183 1184 EXPECT_EQ(EOF, swscanf(L"", L"%ls", wbuf)); 1185 EXPECT_EQ(L'x', wbuf[0]); 1186 } 1187 1188 TEST(STDIO_TEST, scanf_wscanf_wide_character_class) { 1189 #if 0 // TODO: more tests invented during code review; no regressions, so fix later. 1190 wchar_t buf[BUFSIZ]; 1191 1192 // A wide character shouldn't match an ASCII-only class for scanf or wscanf. 1193 memset(buf, 0, sizeof(buf)); 1194 EXPECT_EQ(1, sscanf("xyz", "%l[xy]", buf)); 1195 EXPECT_EQ(L"x"s, std::wstring(buf)); 1196 memset(buf, 0, sizeof(buf)); 1197 EXPECT_EQ(1, swscanf(L"xyz", L"%l[xy]", buf)); 1198 EXPECT_EQ(L"x"s, std::wstring(buf)); 1199 1200 // Even if scanf has wide characters in a class, they won't match... 1201 // TODO: is that a bug? 1202 memset(buf, 0, sizeof(buf)); 1203 EXPECT_EQ(1, sscanf("xyz", "%l[xy]", buf)); 1204 EXPECT_EQ(L"x"s, std::wstring(buf)); 1205 // ...unless you use wscanf. 1206 memset(buf, 0, sizeof(buf)); 1207 EXPECT_EQ(1, swscanf(L"xyz", L"%l[xy]", buf)); 1208 EXPECT_EQ(L"xy"s, std::wstring(buf)); 1209 1210 // Negation only covers ASCII for scanf... 1211 memset(buf, 0, sizeof(buf)); 1212 EXPECT_EQ(1, sscanf("xyz", "%l[^ab]", buf)); 1213 EXPECT_EQ(L"x"s, std::wstring(buf)); 1214 // ...but covers wide characters for wscanf. 1215 memset(buf, 0, sizeof(buf)); 1216 EXPECT_EQ(1, swscanf(L"xyz", L"%l[^ab]", buf)); 1217 EXPECT_EQ(L"xyz"s, std::wstring(buf)); 1218 1219 // We already determined that non-ASCII characters are ignored in scanf classes. 1220 memset(buf, 0, sizeof(buf)); 1221 EXPECT_EQ(1, sscanf("x" 1222 "\xc4\x80" // Matches a byte from each wide char in the class. 1223 "\xc6\x82" // Neither byte is in the class. 1224 "yz", 1225 "%l[xy" "\xc5\x80" "\xc4\x81" "]", buf)); 1226 EXPECT_EQ(L"x", std::wstring(buf)); 1227 // bionic and glibc both behave badly for wscanf, so let's call it right for now... 1228 memset(buf, 0, sizeof(buf)); 1229 EXPECT_EQ(1, swscanf(L"x" 1230 L"\xc4\x80" 1231 L"\xc6\x82" 1232 L"yz", 1233 L"%l[xy" L"\xc5\x80" L"\xc4\x81" L"]", buf)); 1234 // Note that this isn't L"x" --- although the *bytes* matched, they're 1235 // not put back together as a wide character. 1236 EXPECT_EQ(L"x" L"\xc4" L"\x80", std::wstring(buf)); 1237 #endif 1238 } 1239 1240 TEST(STDIO_TEST, cantwrite_EBADF) { 1241 // If we open a file read-only... 1242 FILE* fp = fopen("/proc/version", "r"); 1243 1244 // ...all attempts to write to that file should return failure. 1245 1246 // They should also set errno to EBADF. This isn't POSIX, but it's traditional. 1247 // glibc gets the wide-character functions wrong. 1248 1249 errno = 0; 1250 EXPECT_EQ(EOF, putc('x', fp)); 1251 EXPECT_EQ(EBADF, errno); 1252 1253 errno = 0; 1254 EXPECT_EQ(EOF, fprintf(fp, "hello")); 1255 EXPECT_EQ(EBADF, errno); 1256 1257 errno = 0; 1258 EXPECT_EQ(EOF, fwprintf(fp, L"hello")); 1259 #if defined(__BIONIC__) 1260 EXPECT_EQ(EBADF, errno); 1261 #endif 1262 1263 errno = 0; 1264 EXPECT_EQ(0U, fwrite("hello", 1, 2, fp)); 1265 EXPECT_EQ(EBADF, errno); 1266 1267 errno = 0; 1268 EXPECT_EQ(EOF, fputs("hello", fp)); 1269 EXPECT_EQ(EBADF, errno); 1270 1271 errno = 0; 1272 EXPECT_EQ(WEOF, fputwc(L'x', fp)); 1273 #if defined(__BIONIC__) 1274 EXPECT_EQ(EBADF, errno); 1275 #endif 1276 } 1277 1278 // Tests that we can only have a consistent and correct fpos_t when using 1279 // f*pos functions (i.e. fpos doesn't get inside a multi byte character). 1280 TEST(STDIO_TEST, consistent_fpos_t) { 1281 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 1282 uselocale(LC_GLOBAL_LOCALE); 1283 1284 FILE* fp = tmpfile(); 1285 ASSERT_TRUE(fp != NULL); 1286 1287 wchar_t mb_one_bytes = L'h'; 1288 wchar_t mb_two_bytes = 0x00a2; 1289 wchar_t mb_three_bytes = 0x20ac; 1290 wchar_t mb_four_bytes = 0x24b62; 1291 1292 // Write to file. 1293 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fputwc(mb_one_bytes, fp))); 1294 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 1295 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 1296 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 1297 1298 rewind(fp); 1299 1300 // Record each character position. 1301 fpos_t pos1; 1302 fpos_t pos2; 1303 fpos_t pos3; 1304 fpos_t pos4; 1305 fpos_t pos5; 1306 EXPECT_EQ(0, fgetpos(fp, &pos1)); 1307 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 1308 EXPECT_EQ(0, fgetpos(fp, &pos2)); 1309 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 1310 EXPECT_EQ(0, fgetpos(fp, &pos3)); 1311 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 1312 EXPECT_EQ(0, fgetpos(fp, &pos4)); 1313 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 1314 EXPECT_EQ(0, fgetpos(fp, &pos5)); 1315 1316 #if defined(__BIONIC__) 1317 // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD 1318 // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In 1319 // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE 1320 // structure. 1321 ASSERT_EQ(0, static_cast<off_t>(pos1)); 1322 ASSERT_EQ(1, static_cast<off_t>(pos2)); 1323 ASSERT_EQ(3, static_cast<off_t>(pos3)); 1324 ASSERT_EQ(6, static_cast<off_t>(pos4)); 1325 ASSERT_EQ(10, static_cast<off_t>(pos5)); 1326 #endif 1327 1328 // Exercise back and forth movements of the position. 1329 ASSERT_EQ(0, fsetpos(fp, &pos2)); 1330 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 1331 ASSERT_EQ(0, fsetpos(fp, &pos1)); 1332 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 1333 ASSERT_EQ(0, fsetpos(fp, &pos4)); 1334 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 1335 ASSERT_EQ(0, fsetpos(fp, &pos3)); 1336 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 1337 ASSERT_EQ(0, fsetpos(fp, &pos5)); 1338 ASSERT_EQ(WEOF, fgetwc(fp)); 1339 1340 fclose(fp); 1341 } 1342 1343 // Exercise the interaction between fpos and seek. 1344 TEST(STDIO_TEST, fpos_t_and_seek) { 1345 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 1346 uselocale(LC_GLOBAL_LOCALE); 1347 1348 // In glibc-2.16 fseek doesn't work properly in wide mode 1349 // (https://sourceware.org/bugzilla/show_bug.cgi?id=14543). One workaround is 1350 // to close and re-open the file. We do it in order to make the test pass 1351 // with all glibcs. 1352 1353 TemporaryFile tf; 1354 FILE* fp = fdopen(tf.fd, "w+"); 1355 ASSERT_TRUE(fp != NULL); 1356 1357 wchar_t mb_two_bytes = 0x00a2; 1358 wchar_t mb_three_bytes = 0x20ac; 1359 wchar_t mb_four_bytes = 0x24b62; 1360 1361 // Write to file. 1362 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 1363 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 1364 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 1365 1366 fflush(fp); 1367 fclose(fp); 1368 1369 fp = fopen(tf.filename, "r"); 1370 ASSERT_TRUE(fp != NULL); 1371 1372 // Store a valid position. 1373 fpos_t mb_two_bytes_pos; 1374 ASSERT_EQ(0, fgetpos(fp, &mb_two_bytes_pos)); 1375 1376 // Move inside mb_four_bytes with fseek. 1377 long offset_inside_mb = 6; 1378 ASSERT_EQ(0, fseek(fp, offset_inside_mb, SEEK_SET)); 1379 1380 // Store the "inside multi byte" position. 1381 fpos_t pos_inside_mb; 1382 ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb)); 1383 #if defined(__BIONIC__) 1384 ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb)); 1385 #endif 1386 1387 // Reading from within a byte should produce an error. 1388 ASSERT_EQ(WEOF, fgetwc(fp)); 1389 ASSERT_EQ(EILSEQ, errno); 1390 1391 // Reverting to a valid position should work. 1392 ASSERT_EQ(0, fsetpos(fp, &mb_two_bytes_pos)); 1393 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 1394 1395 // Moving withing a multi byte with fsetpos should work but reading should 1396 // produce an error. 1397 ASSERT_EQ(0, fsetpos(fp, &pos_inside_mb)); 1398 ASSERT_EQ(WEOF, fgetwc(fp)); 1399 ASSERT_EQ(EILSEQ, errno); 1400 1401 ASSERT_EQ(0, fclose(fp)); 1402 } 1403 1404 TEST(STDIO_TEST, fmemopen) { 1405 char buf[16]; 1406 memset(buf, 0, sizeof(buf)); 1407 FILE* fp = fmemopen(buf, sizeof(buf), "r+"); 1408 ASSERT_EQ('<', fputc('<', fp)); 1409 ASSERT_NE(EOF, fputs("abc>\n", fp)); 1410 fflush(fp); 1411 1412 // We wrote to the buffer... 1413 ASSERT_STREQ("<abc>\n", buf); 1414 1415 // And can read back from the file. 1416 AssertFileIs(fp, "<abc>\n", true); 1417 ASSERT_EQ(0, fclose(fp)); 1418 } 1419 1420 TEST(STDIO_TEST, fmemopen_nullptr) { 1421 FILE* fp = fmemopen(nullptr, 128, "r+"); 1422 ASSERT_NE(EOF, fputs("xyz\n", fp)); 1423 1424 AssertFileIs(fp, "xyz\n", true); 1425 ASSERT_EQ(0, fclose(fp)); 1426 } 1427 1428 TEST(STDIO_TEST, fmemopen_trailing_NUL_byte) { 1429 FILE* fp; 1430 char buf[8]; 1431 1432 // POSIX: "When a stream open for writing is flushed or closed, a null byte 1433 // shall be written at the current position or at the end of the buffer, 1434 // depending on the size of the contents." 1435 memset(buf, 'x', sizeof(buf)); 1436 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w")); 1437 // Even with nothing written (and not in truncate mode), we'll flush a NUL... 1438 ASSERT_EQ(0, fflush(fp)); 1439 EXPECT_EQ("\0xxxxxxx"s, std::string(buf, buf + sizeof(buf))); 1440 // Now write and check that the NUL moves along with our writes... 1441 ASSERT_NE(EOF, fputs("hello", fp)); 1442 ASSERT_EQ(0, fflush(fp)); 1443 EXPECT_EQ("hello\0xx"s, std::string(buf, buf + sizeof(buf))); 1444 ASSERT_NE(EOF, fputs("wo", fp)); 1445 ASSERT_EQ(0, fflush(fp)); 1446 EXPECT_EQ("hellowo\0"s, std::string(buf, buf + sizeof(buf))); 1447 ASSERT_EQ(0, fclose(fp)); 1448 1449 // "If a stream open for update is flushed or closed and the last write has 1450 // advanced the current buffer size, a null byte shall be written at the end 1451 // of the buffer if it fits." 1452 memset(buf, 'x', sizeof(buf)); 1453 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r+")); 1454 // Nothing written yet, so no advance... 1455 ASSERT_EQ(0, fflush(fp)); 1456 EXPECT_EQ("xxxxxxxx"s, std::string(buf, buf + sizeof(buf))); 1457 ASSERT_NE(EOF, fputs("hello", fp)); 1458 ASSERT_EQ(0, fclose(fp)); 1459 } 1460 1461 TEST(STDIO_TEST, fmemopen_size) { 1462 FILE* fp; 1463 char buf[16]; 1464 memset(buf, 'x', sizeof(buf)); 1465 1466 // POSIX: "The stream shall also maintain the size of the current buffer 1467 // contents; use of fseek() or fseeko() on the stream with SEEK_END shall 1468 // seek relative to this size." 1469 1470 // "For modes r and r+ the size shall be set to the value given by the size 1471 // argument." 1472 ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "r")); 1473 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1474 EXPECT_EQ(16, ftell(fp)); 1475 EXPECT_EQ(16, ftello(fp)); 1476 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1477 EXPECT_EQ(16, ftell(fp)); 1478 EXPECT_EQ(16, ftello(fp)); 1479 ASSERT_EQ(0, fclose(fp)); 1480 ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "r+")); 1481 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1482 EXPECT_EQ(16, ftell(fp)); 1483 EXPECT_EQ(16, ftello(fp)); 1484 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1485 EXPECT_EQ(16, ftell(fp)); 1486 EXPECT_EQ(16, ftello(fp)); 1487 ASSERT_EQ(0, fclose(fp)); 1488 1489 // "For modes w and w+ the initial size shall be zero..." 1490 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w")); 1491 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1492 EXPECT_EQ(0, ftell(fp)); 1493 EXPECT_EQ(0, ftello(fp)); 1494 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1495 EXPECT_EQ(0, ftell(fp)); 1496 EXPECT_EQ(0, ftello(fp)); 1497 ASSERT_EQ(0, fclose(fp)); 1498 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w+")); 1499 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1500 EXPECT_EQ(0, ftell(fp)); 1501 EXPECT_EQ(0, ftello(fp)); 1502 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1503 EXPECT_EQ(0, ftell(fp)); 1504 EXPECT_EQ(0, ftello(fp)); 1505 ASSERT_EQ(0, fclose(fp)); 1506 1507 // "...and for modes a and a+ the initial size shall be: 1508 // 1. Zero, if buf is a null pointer 1509 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "a")); 1510 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1511 EXPECT_EQ(0, ftell(fp)); 1512 EXPECT_EQ(0, ftello(fp)); 1513 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1514 EXPECT_EQ(0, ftell(fp)); 1515 EXPECT_EQ(0, ftello(fp)); 1516 ASSERT_EQ(0, fclose(fp)); 1517 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "a+")); 1518 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1519 EXPECT_EQ(0, ftell(fp)); 1520 EXPECT_EQ(0, ftello(fp)); 1521 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1522 EXPECT_EQ(0, ftell(fp)); 1523 EXPECT_EQ(0, ftello(fp)); 1524 ASSERT_EQ(0, fclose(fp)); 1525 1526 // 2. The position of the first null byte in the buffer, if one is found 1527 memset(buf, 'x', sizeof(buf)); 1528 buf[3] = '\0'; 1529 ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a")); 1530 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1531 EXPECT_EQ(3, ftell(fp)); 1532 EXPECT_EQ(3, ftello(fp)); 1533 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1534 EXPECT_EQ(3, ftell(fp)); 1535 EXPECT_EQ(3, ftello(fp)); 1536 ASSERT_EQ(0, fclose(fp)); 1537 memset(buf, 'x', sizeof(buf)); 1538 buf[3] = '\0'; 1539 ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a+")); 1540 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1541 EXPECT_EQ(3, ftell(fp)); 1542 EXPECT_EQ(3, ftello(fp)); 1543 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1544 EXPECT_EQ(3, ftell(fp)); 1545 EXPECT_EQ(3, ftello(fp)); 1546 ASSERT_EQ(0, fclose(fp)); 1547 1548 // 3. The value of the size argument, if buf is not a null pointer and no 1549 // null byte is found. 1550 memset(buf, 'x', sizeof(buf)); 1551 ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a")); 1552 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1553 EXPECT_EQ(16, ftell(fp)); 1554 EXPECT_EQ(16, ftello(fp)); 1555 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1556 EXPECT_EQ(16, ftell(fp)); 1557 EXPECT_EQ(16, ftello(fp)); 1558 ASSERT_EQ(0, fclose(fp)); 1559 memset(buf, 'x', sizeof(buf)); 1560 ASSERT_NE(nullptr, fp = fmemopen(buf, 16, "a+")); 1561 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1562 EXPECT_EQ(16, ftell(fp)); 1563 EXPECT_EQ(16, ftello(fp)); 1564 ASSERT_EQ(0, fseeko(fp, 0, SEEK_END)); 1565 EXPECT_EQ(16, ftell(fp)); 1566 EXPECT_EQ(16, ftello(fp)); 1567 ASSERT_EQ(0, fclose(fp)); 1568 } 1569 1570 TEST(STDIO_TEST, fmemopen_SEEK_END) { 1571 // fseek SEEK_END is relative to the current string length, not the buffer size. 1572 FILE* fp; 1573 char buf[8]; 1574 memset(buf, 'x', sizeof(buf)); 1575 strcpy(buf, "str"); 1576 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+")); 1577 ASSERT_NE(EOF, fputs("string", fp)); 1578 EXPECT_EQ(0, fseek(fp, 0, SEEK_END)); 1579 EXPECT_EQ(static_cast<long>(strlen("string")), ftell(fp)); 1580 EXPECT_EQ(static_cast<off_t>(strlen("string")), ftello(fp)); 1581 EXPECT_EQ(0, fclose(fp)); 1582 1583 // glibc < 2.22 interpreted SEEK_END the wrong way round (subtracting rather 1584 // than adding). 1585 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+")); 1586 ASSERT_NE(EOF, fputs("54321", fp)); 1587 EXPECT_EQ(0, fseek(fp, -2, SEEK_END)); 1588 EXPECT_EQ('2', fgetc(fp)); 1589 EXPECT_EQ(0, fclose(fp)); 1590 } 1591 1592 TEST(STDIO_TEST, fmemopen_seek_invalid) { 1593 char buf[8]; 1594 memset(buf, 'x', sizeof(buf)); 1595 FILE* fp = fmemopen(buf, sizeof(buf), "w"); 1596 ASSERT_TRUE(fp != nullptr); 1597 1598 // POSIX: "An attempt to seek ... to a negative position or to a position 1599 // larger than the buffer size given in the size argument shall fail." 1600 // (There's no mention of what errno should be set to, and glibc doesn't 1601 // set errno in any of these cases.) 1602 EXPECT_EQ(-1, fseek(fp, -2, SEEK_SET)); 1603 EXPECT_EQ(-1, fseeko(fp, -2, SEEK_SET)); 1604 EXPECT_EQ(-1, fseek(fp, sizeof(buf) + 1, SEEK_SET)); 1605 EXPECT_EQ(-1, fseeko(fp, sizeof(buf) + 1, SEEK_SET)); 1606 } 1607 1608 TEST(STDIO_TEST, fmemopen_read_EOF) { 1609 // POSIX: "A read operation on the stream shall not advance the current 1610 // buffer position beyond the current buffer size." 1611 char buf[8]; 1612 memset(buf, 'x', sizeof(buf)); 1613 FILE* fp = fmemopen(buf, sizeof(buf), "r"); 1614 ASSERT_TRUE(fp != nullptr); 1615 char buf2[BUFSIZ]; 1616 ASSERT_EQ(8U, fread(buf2, 1, sizeof(buf2), fp)); 1617 // POSIX: "Reaching the buffer size in a read operation shall count as 1618 // end-of-file. 1619 ASSERT_TRUE(feof(fp)); 1620 ASSERT_EQ(EOF, fgetc(fp)); 1621 ASSERT_EQ(0, fclose(fp)); 1622 } 1623 1624 TEST(STDIO_TEST, fmemopen_read_null_bytes) { 1625 // POSIX: "Null bytes in the buffer shall have no special meaning for reads." 1626 char buf[] = "h\0e\0l\0l\0o"; 1627 FILE* fp = fmemopen(buf, sizeof(buf), "r"); 1628 ASSERT_TRUE(fp != nullptr); 1629 ASSERT_EQ('h', fgetc(fp)); 1630 ASSERT_EQ(0, fgetc(fp)); 1631 ASSERT_EQ('e', fgetc(fp)); 1632 ASSERT_EQ(0, fgetc(fp)); 1633 ASSERT_EQ('l', fgetc(fp)); 1634 ASSERT_EQ(0, fgetc(fp)); 1635 // POSIX: "The read operation shall start at the current buffer position of 1636 // the stream." 1637 char buf2[8]; 1638 memset(buf2, 'x', sizeof(buf2)); 1639 ASSERT_EQ(4U, fread(buf2, 1, sizeof(buf2), fp)); 1640 ASSERT_EQ('l', buf2[0]); 1641 ASSERT_EQ(0, buf2[1]); 1642 ASSERT_EQ('o', buf2[2]); 1643 ASSERT_EQ(0, buf2[3]); 1644 for (size_t i = 4; i < sizeof(buf2); ++i) ASSERT_EQ('x', buf2[i]) << i; 1645 ASSERT_TRUE(feof(fp)); 1646 ASSERT_EQ(0, fclose(fp)); 1647 } 1648 1649 TEST(STDIO_TEST, fmemopen_write) { 1650 FILE* fp; 1651 char buf[8]; 1652 1653 // POSIX: "A write operation shall start either at the current position of 1654 // the stream (if mode has not specified 'a' as the first character)..." 1655 memset(buf, 'x', sizeof(buf)); 1656 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r+")); 1657 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1658 ASSERT_EQ(0, fseek(fp, 2, SEEK_SET)); 1659 ASSERT_EQ(' ', fputc(' ', fp)); 1660 EXPECT_EQ("xx xxxxx", std::string(buf, buf + sizeof(buf))); 1661 ASSERT_EQ(0, fclose(fp)); 1662 1663 // "...or at the current size of the stream (if mode had 'a' as the first 1664 // character)." (See the fmemopen_size test for what "size" means, but for 1665 // mode "a", it's the first NUL byte.) 1666 memset(buf, 'x', sizeof(buf)); 1667 buf[3] = '\0'; 1668 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a+")); 1669 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1670 ASSERT_EQ(' ', fputc(' ', fp)); 1671 EXPECT_EQ("xxx \0xxx"s, std::string(buf, buf + sizeof(buf))); 1672 ASSERT_EQ(0, fclose(fp)); 1673 1674 // "If the current position at the end of the write is larger than the 1675 // current buffer size, the current buffer size shall be set to the current 1676 // position." (See the fmemopen_size test for what "size" means, but to 1677 // query it we SEEK_END with offset 0, and then ftell.) 1678 memset(buf, 'x', sizeof(buf)); 1679 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w+")); 1680 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1681 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1682 EXPECT_EQ(0, ftell(fp)); 1683 ASSERT_EQ(' ', fputc(' ', fp)); 1684 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1685 EXPECT_EQ(1, ftell(fp)); 1686 ASSERT_NE(EOF, fputs("123", fp)); 1687 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1688 EXPECT_EQ(4, ftell(fp)); 1689 EXPECT_EQ(" 123\0xxx"s, std::string(buf, buf + sizeof(buf))); 1690 ASSERT_EQ(0, fclose(fp)); 1691 } 1692 1693 TEST(STDIO_TEST, fmemopen_write_EOF) { 1694 // POSIX: "A write operation on the stream shall not advance the current 1695 // buffer size beyond the size given in the size argument." 1696 FILE* fp; 1697 1698 // Scalar writes... 1699 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 4, "w")); 1700 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1701 ASSERT_EQ('x', fputc('x', fp)); 1702 ASSERT_EQ('x', fputc('x', fp)); 1703 ASSERT_EQ('x', fputc('x', fp)); 1704 ASSERT_EQ(EOF, fputc('x', fp)); // Only 3 fit because of the implicit NUL. 1705 ASSERT_EQ(0, fclose(fp)); 1706 1707 // Vector writes... 1708 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 4, "w")); 1709 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1710 ASSERT_EQ(3U, fwrite("xxxx", 1, 4, fp)); 1711 ASSERT_EQ(0, fclose(fp)); 1712 } 1713 1714 TEST(STDIO_TEST, fmemopen_initial_position) { 1715 // POSIX: "The ... current position in the buffer ... shall be initially 1716 // set to either the beginning of the buffer (for r and w modes) ..." 1717 char buf[] = "hello\0world"; 1718 FILE* fp; 1719 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "r")); 1720 EXPECT_EQ(0L, ftell(fp)); 1721 EXPECT_EQ(0, fclose(fp)); 1722 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "w")); 1723 EXPECT_EQ(0L, ftell(fp)); 1724 EXPECT_EQ(0, fclose(fp)); 1725 buf[0] = 'h'; // (Undo the effects of the above.) 1726 1727 // POSIX: "...or to the first null byte in the buffer (for a modes)." 1728 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a")); 1729 EXPECT_EQ(5L, ftell(fp)); 1730 EXPECT_EQ(0, fclose(fp)); 1731 1732 // POSIX: "If no null byte is found in append mode, the initial position 1733 // shall be set to one byte after the end of the buffer." 1734 memset(buf, 'x', sizeof(buf)); 1735 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a")); 1736 EXPECT_EQ(static_cast<long>(sizeof(buf)), ftell(fp)); 1737 EXPECT_EQ(0, fclose(fp)); 1738 } 1739 1740 TEST(STDIO_TEST, fmemopen_initial_position_allocated) { 1741 // POSIX: "If buf is a null pointer, the initial position shall always be 1742 // set to the beginning of the buffer." 1743 FILE* fp = fmemopen(nullptr, 128, "a+"); 1744 ASSERT_TRUE(fp != nullptr); 1745 EXPECT_EQ(0L, ftell(fp)); 1746 EXPECT_EQ(0L, fseek(fp, 0, SEEK_SET)); 1747 EXPECT_EQ(0, fclose(fp)); 1748 } 1749 1750 TEST(STDIO_TEST, fmemopen_zero_length) { 1751 // POSIX says it's up to the implementation whether or not you can have a 1752 // zero-length buffer (but "A future version of this standard may require 1753 // support of zero-length buffer streams explicitly"). BSD and glibc < 2.22 1754 // agreed that you couldn't, but glibc >= 2.22 allows it for consistency. 1755 FILE* fp; 1756 char buf[16]; 1757 ASSERT_NE(nullptr, fp = fmemopen(buf, 0, "r+")); 1758 ASSERT_EQ(EOF, fgetc(fp)); 1759 ASSERT_TRUE(feof(fp)); 1760 ASSERT_EQ(0, fclose(fp)); 1761 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 0, "r+")); 1762 ASSERT_EQ(EOF, fgetc(fp)); 1763 ASSERT_TRUE(feof(fp)); 1764 ASSERT_EQ(0, fclose(fp)); 1765 1766 ASSERT_NE(nullptr, fp = fmemopen(buf, 0, "w+")); 1767 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1768 ASSERT_EQ(EOF, fputc('x', fp)); 1769 ASSERT_EQ(0, fclose(fp)); 1770 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 0, "w+")); 1771 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1772 ASSERT_EQ(EOF, fputc('x', fp)); 1773 ASSERT_EQ(0, fclose(fp)); 1774 } 1775 1776 TEST(STDIO_TEST, fmemopen_write_only_allocated) { 1777 // POSIX says fmemopen "may fail if the mode argument does not include a '+'". 1778 // BSD fails, glibc doesn't. We side with the more lenient. 1779 FILE* fp; 1780 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "r")); 1781 ASSERT_EQ(0, fclose(fp)); 1782 ASSERT_NE(nullptr, fp = fmemopen(nullptr, 16, "w")); 1783 ASSERT_EQ(0, fclose(fp)); 1784 } 1785 1786 TEST(STDIO_TEST, fmemopen_fileno) { 1787 // There's no fd backing an fmemopen FILE*. 1788 FILE* fp = fmemopen(nullptr, 16, "r"); 1789 ASSERT_TRUE(fp != nullptr); 1790 errno = 0; 1791 ASSERT_EQ(-1, fileno(fp)); 1792 ASSERT_EQ(EBADF, errno); 1793 ASSERT_EQ(0, fclose(fp)); 1794 } 1795 1796 TEST(STDIO_TEST, fmemopen_append_after_seek) { 1797 // In BSD and glibc < 2.22, append mode didn't force writes to append if 1798 // there had been an intervening seek. 1799 1800 FILE* fp; 1801 char buf[] = "hello\0world"; 1802 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a")); 1803 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1804 ASSERT_EQ(0, fseek(fp, 0, SEEK_SET)); 1805 ASSERT_NE(EOF, fputc('!', fp)); 1806 EXPECT_EQ("hello!\0orld\0"s, std::string(buf, buf + sizeof(buf))); 1807 ASSERT_EQ(0, fclose(fp)); 1808 1809 memcpy(buf, "hello\0world", sizeof(buf)); 1810 ASSERT_NE(nullptr, fp = fmemopen(buf, sizeof(buf), "a+")); 1811 setbuf(fp, nullptr); // Turn off buffering so we can see what's happening as it happens. 1812 ASSERT_EQ(0, fseek(fp, 0, SEEK_SET)); 1813 ASSERT_NE(EOF, fputc('!', fp)); 1814 EXPECT_EQ("hello!\0orld\0"s, std::string(buf, buf + sizeof(buf))); 1815 ASSERT_EQ(0, fclose(fp)); 1816 } 1817 1818 TEST(STDIO_TEST, open_memstream) { 1819 char* p = nullptr; 1820 size_t size = 0; 1821 FILE* fp = open_memstream(&p, &size); 1822 ASSERT_NE(EOF, fputs("hello, world!", fp)); 1823 fclose(fp); 1824 1825 ASSERT_STREQ("hello, world!", p); 1826 ASSERT_EQ(strlen("hello, world!"), size); 1827 free(p); 1828 } 1829 1830 TEST(STDIO_TEST, open_memstream_EINVAL) { 1831 #if defined(__BIONIC__) 1832 char* p; 1833 size_t size; 1834 1835 // Invalid buffer. 1836 errno = 0; 1837 ASSERT_EQ(nullptr, open_memstream(nullptr, &size)); 1838 ASSERT_EQ(EINVAL, errno); 1839 1840 // Invalid size. 1841 errno = 0; 1842 ASSERT_EQ(nullptr, open_memstream(&p, nullptr)); 1843 ASSERT_EQ(EINVAL, errno); 1844 #else 1845 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n"; 1846 #endif 1847 } 1848 1849 TEST(STDIO_TEST, fdopen_CLOEXEC) { 1850 int fd = open("/proc/version", O_RDONLY); 1851 ASSERT_TRUE(fd != -1); 1852 1853 // This fd doesn't have O_CLOEXEC... 1854 AssertCloseOnExec(fd, false); 1855 1856 FILE* fp = fdopen(fd, "re"); 1857 ASSERT_TRUE(fp != NULL); 1858 1859 // ...but the new one does. 1860 AssertCloseOnExec(fileno(fp), true); 1861 1862 fclose(fp); 1863 close(fd); 1864 } 1865 1866 TEST(STDIO_TEST, freopen_CLOEXEC) { 1867 FILE* fp = fopen("/proc/version", "r"); 1868 ASSERT_TRUE(fp != NULL); 1869 1870 // This FILE* doesn't have O_CLOEXEC... 1871 AssertCloseOnExec(fileno(fp), false); 1872 1873 fp = freopen("/proc/version", "re", fp); 1874 1875 // ...but the new one does. 1876 AssertCloseOnExec(fileno(fp), true); 1877 1878 fclose(fp); 1879 } 1880 1881 TEST(STDIO_TEST, fopen64_freopen64) { 1882 FILE* fp = fopen64("/proc/version", "r"); 1883 ASSERT_TRUE(fp != nullptr); 1884 fp = freopen64("/proc/version", "re", fp); 1885 ASSERT_TRUE(fp != nullptr); 1886 fclose(fp); 1887 } 1888 1889 // https://code.google.com/p/android/issues/detail?id=81155 1890 // http://b/18556607 1891 TEST(STDIO_TEST, fread_unbuffered_pathological_performance) { 1892 FILE* fp = fopen("/dev/zero", "r"); 1893 ASSERT_TRUE(fp != NULL); 1894 1895 // Make this stream unbuffered. 1896 setvbuf(fp, 0, _IONBF, 0); 1897 1898 char buf[65*1024]; 1899 memset(buf, 0xff, sizeof(buf)); 1900 1901 time_t t0 = time(NULL); 1902 for (size_t i = 0; i < 1024; ++i) { 1903 ASSERT_EQ(1U, fread(buf, 64*1024, 1, fp)); 1904 } 1905 time_t t1 = time(NULL); 1906 1907 fclose(fp); 1908 1909 // 1024 64KiB reads should have been very quick. 1910 ASSERT_LE(t1 - t0, 1); 1911 1912 for (size_t i = 0; i < 64*1024; ++i) { 1913 ASSERT_EQ('\0', buf[i]); 1914 } 1915 for (size_t i = 64*1024; i < 65*1024; ++i) { 1916 ASSERT_EQ('\xff', buf[i]); 1917 } 1918 } 1919 1920 TEST(STDIO_TEST, fread_EOF) { 1921 std::string digits("0123456789"); 1922 FILE* fp = fmemopen(&digits[0], digits.size(), "r"); 1923 1924 // Try to read too much, but little enough that it still fits in the FILE's internal buffer. 1925 char buf1[4 * 4]; 1926 memset(buf1, 0, sizeof(buf1)); 1927 ASSERT_EQ(2U, fread(buf1, 4, 4, fp)); 1928 ASSERT_STREQ("0123456789", buf1); 1929 ASSERT_TRUE(feof(fp)); 1930 1931 rewind(fp); 1932 1933 // Try to read way too much so stdio tries to read more direct from the stream. 1934 char buf2[4 * 4096]; 1935 memset(buf2, 0, sizeof(buf2)); 1936 ASSERT_EQ(2U, fread(buf2, 4, 4096, fp)); 1937 ASSERT_STREQ("0123456789", buf2); 1938 ASSERT_TRUE(feof(fp)); 1939 1940 fclose(fp); 1941 } 1942 1943 static void test_fread_from_write_only_stream(size_t n) { 1944 FILE* fp = fopen("/dev/null", "w"); 1945 std::vector<char> buf(n, 0); 1946 errno = 0; 1947 ASSERT_EQ(0U, fread(&buf[0], n, 1, fp)); 1948 ASSERT_EQ(EBADF, errno); 1949 ASSERT_TRUE(ferror(fp)); 1950 ASSERT_FALSE(feof(fp)); 1951 fclose(fp); 1952 } 1953 1954 TEST(STDIO_TEST, fread_from_write_only_stream_slow_path) { 1955 test_fread_from_write_only_stream(1); 1956 } 1957 1958 TEST(STDIO_TEST, fread_from_write_only_stream_fast_path) { 1959 test_fread_from_write_only_stream(64*1024); 1960 } 1961 1962 static void test_fwrite_after_fread(size_t n) { 1963 TemporaryFile tf; 1964 1965 FILE* fp = fdopen(tf.fd, "w+"); 1966 ASSERT_EQ(1U, fwrite("1", 1, 1, fp)); 1967 fflush(fp); 1968 1969 // We've flushed but not rewound, so there's nothing to read. 1970 std::vector<char> buf(n, 0); 1971 ASSERT_EQ(0U, fread(&buf[0], 1, buf.size(), fp)); 1972 ASSERT_TRUE(feof(fp)); 1973 1974 // But hitting EOF doesn't prevent us from writing... 1975 errno = 0; 1976 ASSERT_EQ(1U, fwrite("2", 1, 1, fp)) << strerror(errno); 1977 1978 // And if we rewind, everything's there. 1979 rewind(fp); 1980 ASSERT_EQ(2U, fread(&buf[0], 1, buf.size(), fp)); 1981 ASSERT_EQ('1', buf[0]); 1982 ASSERT_EQ('2', buf[1]); 1983 1984 fclose(fp); 1985 } 1986 1987 TEST(STDIO_TEST, fwrite_after_fread_slow_path) { 1988 test_fwrite_after_fread(16); 1989 } 1990 1991 TEST(STDIO_TEST, fwrite_after_fread_fast_path) { 1992 test_fwrite_after_fread(64*1024); 1993 } 1994 1995 // http://b/19172514 1996 TEST(STDIO_TEST, fread_after_fseek) { 1997 TemporaryFile tf; 1998 1999 FILE* fp = fopen(tf.filename, "w+"); 2000 ASSERT_TRUE(fp != nullptr); 2001 2002 char file_data[12288]; 2003 for (size_t i = 0; i < 12288; i++) { 2004 file_data[i] = i; 2005 } 2006 ASSERT_EQ(12288U, fwrite(file_data, 1, 12288, fp)); 2007 fclose(fp); 2008 2009 fp = fopen(tf.filename, "r"); 2010 ASSERT_TRUE(fp != nullptr); 2011 2012 char buffer[8192]; 2013 size_t cur_location = 0; 2014 // Small read to populate internal buffer. 2015 ASSERT_EQ(100U, fread(buffer, 1, 100, fp)); 2016 ASSERT_EQ(memcmp(file_data, buffer, 100), 0); 2017 2018 cur_location = static_cast<size_t>(ftell(fp)); 2019 // Large read to force reading into the user supplied buffer and bypassing 2020 // the internal buffer. 2021 ASSERT_EQ(8192U, fread(buffer, 1, 8192, fp)); 2022 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0); 2023 2024 // Small backwards seek to verify fseek does not reuse the internal buffer. 2025 ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR)) << strerror(errno); 2026 cur_location = static_cast<size_t>(ftell(fp)); 2027 ASSERT_EQ(22U, fread(buffer, 1, 22, fp)); 2028 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0); 2029 2030 fclose(fp); 2031 } 2032 2033 // https://code.google.com/p/android/issues/detail?id=184847 2034 TEST(STDIO_TEST, fread_EOF_184847) { 2035 TemporaryFile tf; 2036 char buf[6] = {0}; 2037 2038 FILE* fw = fopen(tf.filename, "w"); 2039 ASSERT_TRUE(fw != nullptr); 2040 2041 FILE* fr = fopen(tf.filename, "r"); 2042 ASSERT_TRUE(fr != nullptr); 2043 2044 fwrite("a", 1, 1, fw); 2045 fflush(fw); 2046 ASSERT_EQ(1U, fread(buf, 1, 1, fr)); 2047 ASSERT_STREQ("a", buf); 2048 2049 // 'fr' is now at EOF. 2050 ASSERT_EQ(0U, fread(buf, 1, 1, fr)); 2051 ASSERT_TRUE(feof(fr)); 2052 2053 // Write some more... 2054 fwrite("z", 1, 1, fw); 2055 fflush(fw); 2056 2057 // ...and check that we can read it back. 2058 // (BSD thinks that once a stream has hit EOF, it must always return EOF. SysV disagrees.) 2059 ASSERT_EQ(1U, fread(buf, 1, 1, fr)); 2060 ASSERT_STREQ("z", buf); 2061 2062 // But now we're done. 2063 ASSERT_EQ(0U, fread(buf, 1, 1, fr)); 2064 2065 fclose(fr); 2066 fclose(fw); 2067 } 2068 2069 TEST(STDIO_TEST, fclose_invalidates_fd) { 2070 // The typical error we're trying to help people catch involves accessing 2071 // memory after it's been freed. But we know that stdin/stdout/stderr are 2072 // special and don't get deallocated, so this test uses stdin. 2073 ASSERT_EQ(0, fclose(stdin)); 2074 2075 // Even though using a FILE* after close is undefined behavior, I've closed 2076 // this bug as "WAI" too many times. We shouldn't hand out stale fds, 2077 // especially because they might actually correspond to a real stream. 2078 errno = 0; 2079 ASSERT_EQ(-1, fileno(stdin)); 2080 ASSERT_EQ(EBADF, errno); 2081 } 2082 2083 TEST(STDIO_TEST, fseek_ftell_unseekable) { 2084 #if defined(__BIONIC__) // glibc has fopencookie instead. 2085 auto read_fn = [](void*, char*, int) { return -1; }; 2086 FILE* fp = funopen(nullptr, read_fn, nullptr, nullptr, nullptr); 2087 ASSERT_TRUE(fp != nullptr); 2088 2089 // Check that ftell balks on an unseekable FILE*. 2090 errno = 0; 2091 ASSERT_EQ(-1, ftell(fp)); 2092 ASSERT_EQ(ESPIPE, errno); 2093 2094 // SEEK_CUR is rewritten as SEEK_SET internally... 2095 errno = 0; 2096 ASSERT_EQ(-1, fseek(fp, 0, SEEK_CUR)); 2097 ASSERT_EQ(ESPIPE, errno); 2098 2099 // ...so it's worth testing the direct seek path too. 2100 errno = 0; 2101 ASSERT_EQ(-1, fseek(fp, 0, SEEK_SET)); 2102 ASSERT_EQ(ESPIPE, errno); 2103 2104 fclose(fp); 2105 #else 2106 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 2107 #endif 2108 } 2109 2110 TEST(STDIO_TEST, funopen_EINVAL) { 2111 #if defined(__BIONIC__) 2112 errno = 0; 2113 ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr)); 2114 ASSERT_EQ(EINVAL, errno); 2115 #else 2116 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 2117 #endif 2118 } 2119 2120 TEST(STDIO_TEST, funopen_seek) { 2121 #if defined(__BIONIC__) 2122 auto read_fn = [](void*, char*, int) { return -1; }; 2123 2124 auto seek_fn = [](void*, fpos_t, int) -> fpos_t { return 0xfedcba12; }; 2125 auto seek64_fn = [](void*, fpos64_t, int) -> fpos64_t { return 0xfedcba12345678; }; 2126 2127 FILE* fp = funopen(nullptr, read_fn, nullptr, seek_fn, nullptr); 2128 ASSERT_TRUE(fp != nullptr); 2129 fpos_t pos; 2130 #if defined(__LP64__) 2131 EXPECT_EQ(0, fgetpos(fp, &pos)) << strerror(errno); 2132 EXPECT_EQ(0xfedcba12LL, pos); 2133 #else 2134 EXPECT_EQ(-1, fgetpos(fp, &pos)) << strerror(errno); 2135 EXPECT_EQ(EOVERFLOW, errno); 2136 #endif 2137 2138 FILE* fp64 = funopen64(nullptr, read_fn, nullptr, seek64_fn, nullptr); 2139 ASSERT_TRUE(fp64 != nullptr); 2140 fpos64_t pos64; 2141 EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno); 2142 EXPECT_EQ(0xfedcba12345678, pos64); 2143 #else 2144 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 2145 #endif 2146 } 2147 2148 TEST(STDIO_TEST, lots_of_concurrent_files) { 2149 std::vector<TemporaryFile*> tfs; 2150 std::vector<FILE*> fps; 2151 2152 for (size_t i = 0; i < 256; ++i) { 2153 TemporaryFile* tf = new TemporaryFile; 2154 tfs.push_back(tf); 2155 FILE* fp = fopen(tf->filename, "w+"); 2156 fps.push_back(fp); 2157 fprintf(fp, "hello %zu!\n", i); 2158 fflush(fp); 2159 } 2160 2161 for (size_t i = 0; i < 256; ++i) { 2162 char expected[BUFSIZ]; 2163 snprintf(expected, sizeof(expected), "hello %zu!\n", i); 2164 2165 AssertFileIs(fps[i], expected); 2166 fclose(fps[i]); 2167 delete tfs[i]; 2168 } 2169 } 2170 2171 static void AssertFileOffsetAt(FILE* fp, off64_t offset) { 2172 EXPECT_EQ(offset, ftell(fp)); 2173 EXPECT_EQ(offset, ftello(fp)); 2174 EXPECT_EQ(offset, ftello64(fp)); 2175 fpos_t pos; 2176 fpos64_t pos64; 2177 EXPECT_EQ(0, fgetpos(fp, &pos)); 2178 EXPECT_EQ(0, fgetpos64(fp, &pos64)); 2179 #if defined(__BIONIC__) 2180 EXPECT_EQ(offset, static_cast<off64_t>(pos)); 2181 EXPECT_EQ(offset, static_cast<off64_t>(pos64)); 2182 #else 2183 GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n"; 2184 #endif 2185 } 2186 2187 TEST(STDIO_TEST, seek_tell_family_smoke) { 2188 TemporaryFile tf; 2189 FILE* fp = fdopen(tf.fd, "w+"); 2190 2191 // Initially we should be at 0. 2192 AssertFileOffsetAt(fp, 0); 2193 2194 // Seek to offset 8192. 2195 ASSERT_EQ(0, fseek(fp, 8192, SEEK_SET)); 2196 AssertFileOffsetAt(fp, 8192); 2197 fpos_t eight_k_pos; 2198 ASSERT_EQ(0, fgetpos(fp, &eight_k_pos)); 2199 2200 // Seek forward another 8192... 2201 ASSERT_EQ(0, fseek(fp, 8192, SEEK_CUR)); 2202 AssertFileOffsetAt(fp, 8192 + 8192); 2203 fpos64_t sixteen_k_pos64; 2204 ASSERT_EQ(0, fgetpos64(fp, &sixteen_k_pos64)); 2205 2206 // Seek back 8192... 2207 ASSERT_EQ(0, fseek(fp, -8192, SEEK_CUR)); 2208 AssertFileOffsetAt(fp, 8192); 2209 2210 // Since we haven't written anything, the end is also at 0. 2211 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 2212 AssertFileOffsetAt(fp, 0); 2213 2214 // Check that our fpos64_t from 16KiB works... 2215 ASSERT_EQ(0, fsetpos64(fp, &sixteen_k_pos64)); 2216 AssertFileOffsetAt(fp, 8192 + 8192); 2217 // ...as does our fpos_t from 8192. 2218 ASSERT_EQ(0, fsetpos(fp, &eight_k_pos)); 2219 AssertFileOffsetAt(fp, 8192); 2220 2221 // Do fseeko and fseeko64 work too? 2222 ASSERT_EQ(0, fseeko(fp, 1234, SEEK_SET)); 2223 AssertFileOffsetAt(fp, 1234); 2224 ASSERT_EQ(0, fseeko64(fp, 5678, SEEK_SET)); 2225 AssertFileOffsetAt(fp, 5678); 2226 2227 fclose(fp); 2228 } 2229 2230 TEST(STDIO_TEST, fseek_fseeko_EINVAL) { 2231 TemporaryFile tf; 2232 FILE* fp = fdopen(tf.fd, "w+"); 2233 2234 // Bad whence. 2235 errno = 0; 2236 ASSERT_EQ(-1, fseek(fp, 0, 123)); 2237 ASSERT_EQ(EINVAL, errno); 2238 errno = 0; 2239 ASSERT_EQ(-1, fseeko(fp, 0, 123)); 2240 ASSERT_EQ(EINVAL, errno); 2241 errno = 0; 2242 ASSERT_EQ(-1, fseeko64(fp, 0, 123)); 2243 ASSERT_EQ(EINVAL, errno); 2244 2245 // Bad offset. 2246 errno = 0; 2247 ASSERT_EQ(-1, fseek(fp, -1, SEEK_SET)); 2248 ASSERT_EQ(EINVAL, errno); 2249 errno = 0; 2250 ASSERT_EQ(-1, fseeko(fp, -1, SEEK_SET)); 2251 ASSERT_EQ(EINVAL, errno); 2252 errno = 0; 2253 ASSERT_EQ(-1, fseeko64(fp, -1, SEEK_SET)); 2254 ASSERT_EQ(EINVAL, errno); 2255 2256 fclose(fp); 2257 } 2258 2259 TEST(STDIO_TEST, ctermid) { 2260 ASSERT_STREQ("/dev/tty", ctermid(nullptr)); 2261 2262 char buf[L_ctermid] = {}; 2263 ASSERT_EQ(buf, ctermid(buf)); 2264 ASSERT_STREQ("/dev/tty", buf); 2265 } 2266 2267 TEST(STDIO_TEST, remove) { 2268 struct stat sb; 2269 2270 TemporaryFile tf; 2271 ASSERT_EQ(0, remove(tf.filename)); 2272 ASSERT_EQ(-1, lstat(tf.filename, &sb)); 2273 ASSERT_EQ(ENOENT, errno); 2274 2275 TemporaryDir td; 2276 ASSERT_EQ(0, remove(td.dirname)); 2277 ASSERT_EQ(-1, lstat(td.dirname, &sb)); 2278 ASSERT_EQ(ENOENT, errno); 2279 2280 errno = 0; 2281 ASSERT_EQ(-1, remove(tf.filename)); 2282 ASSERT_EQ(ENOENT, errno); 2283 2284 errno = 0; 2285 ASSERT_EQ(-1, remove(td.dirname)); 2286 ASSERT_EQ(ENOENT, errno); 2287 } 2288 2289 TEST(STDIO_DEATHTEST, snprintf_30445072_known_buffer_size) { 2290 char buf[16]; 2291 ASSERT_EXIT(snprintf(buf, atol("-1"), "hello"), 2292 testing::KilledBySignal(SIGABRT), 2293 #if defined(NOFORTIFY) 2294 "FORTIFY: vsnprintf: size .* > SSIZE_MAX" 2295 #else 2296 "FORTIFY: vsnprintf: prevented .*-byte write into 16-byte buffer" 2297 #endif 2298 ); 2299 } 2300 2301 TEST(STDIO_DEATHTEST, snprintf_30445072_unknown_buffer_size) { 2302 std::string buf = "world"; 2303 ASSERT_EXIT(snprintf(&buf[0], atol("-1"), "hello"), 2304 testing::KilledBySignal(SIGABRT), 2305 "FORTIFY: vsnprintf: size .* > SSIZE_MAX"); 2306 } 2307 2308 TEST(STDIO_TEST, sprintf_30445072) { 2309 std::string buf = "world"; 2310 sprintf(&buf[0], "hello"); 2311 ASSERT_EQ(buf, "hello"); 2312 } 2313 2314 TEST(STDIO_TEST, fopen_append_mode_and_ftell) { 2315 TemporaryFile tf; 2316 SetFileTo(tf.filename, "0123456789"); 2317 FILE* fp = fopen(tf.filename, "a"); 2318 EXPECT_EQ(10, ftell(fp)); 2319 ASSERT_EQ(0, fseek(fp, 2, SEEK_SET)); 2320 EXPECT_EQ(2, ftell(fp)); 2321 ASSERT_NE(EOF, fputs("xxx", fp)); 2322 ASSERT_EQ(0, fflush(fp)); 2323 EXPECT_EQ(13, ftell(fp)); 2324 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 2325 EXPECT_EQ(13, ftell(fp)); 2326 ASSERT_EQ(0, fclose(fp)); 2327 AssertFileIs(tf.filename, "0123456789xxx"); 2328 } 2329 2330 TEST(STDIO_TEST, fdopen_append_mode_and_ftell) { 2331 TemporaryFile tf; 2332 SetFileTo(tf.filename, "0123456789"); 2333 int fd = open(tf.filename, O_RDWR); 2334 ASSERT_NE(-1, fd); 2335 // POSIX: "The file position indicator associated with the new stream is set to the position 2336 // indicated by the file offset associated with the file descriptor." 2337 ASSERT_EQ(4, lseek(fd, 4, SEEK_SET)); 2338 FILE* fp = fdopen(fd, "a"); 2339 EXPECT_EQ(4, ftell(fp)); 2340 ASSERT_EQ(0, fseek(fp, 2, SEEK_SET)); 2341 EXPECT_EQ(2, ftell(fp)); 2342 ASSERT_NE(EOF, fputs("xxx", fp)); 2343 ASSERT_EQ(0, fflush(fp)); 2344 EXPECT_EQ(13, ftell(fp)); 2345 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 2346 EXPECT_EQ(13, ftell(fp)); 2347 ASSERT_EQ(0, fclose(fp)); 2348 AssertFileIs(tf.filename, "0123456789xxx"); 2349 } 2350 2351 TEST(STDIO_TEST, freopen_append_mode_and_ftell) { 2352 TemporaryFile tf; 2353 SetFileTo(tf.filename, "0123456789"); 2354 FILE* other_fp = fopen("/proc/version", "r"); 2355 FILE* fp = freopen(tf.filename, "a", other_fp); 2356 EXPECT_EQ(10, ftell(fp)); 2357 ASSERT_EQ(0, fseek(fp, 2, SEEK_SET)); 2358 EXPECT_EQ(2, ftell(fp)); 2359 ASSERT_NE(EOF, fputs("xxx", fp)); 2360 ASSERT_EQ(0, fflush(fp)); 2361 EXPECT_EQ(13, ftell(fp)); 2362 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 2363 EXPECT_EQ(13, ftell(fp)); 2364 ASSERT_EQ(0, fclose(fp)); 2365 AssertFileIs(tf.filename, "0123456789xxx"); 2366 } 2367 2368 TEST(STDIO_TEST, constants) { 2369 ASSERT_LE(FILENAME_MAX, PATH_MAX); 2370 ASSERT_EQ(L_tmpnam, PATH_MAX); 2371 } 2372 2373 TEST(STDIO_TEST, perror) { 2374 ExecTestHelper eth; 2375 eth.Run([&]() { errno = EINVAL; perror("a b c"); exit(0); }, 0, "a b c: Invalid argument\n"); 2376 eth.Run([&]() { errno = EINVAL; perror(nullptr); exit(0); }, 0, "Invalid argument\n"); 2377 eth.Run([&]() { errno = EINVAL; perror(""); exit(0); }, 0, "Invalid argument\n"); 2378 } 2379 2380 TEST(STDIO_TEST, puts) { 2381 ExecTestHelper eth; 2382 eth.Run([&]() { exit(puts("a b c")); }, 0, "a b c\n"); 2383 } 2384 2385 TEST(STDIO_TEST, unlocked) { 2386 TemporaryFile tf; 2387 2388 FILE* fp = fopen(tf.filename, "w+"); 2389 ASSERT_TRUE(fp != nullptr); 2390 2391 clearerr_unlocked(fp); 2392 ASSERT_FALSE(feof_unlocked(fp)); 2393 ASSERT_FALSE(ferror_unlocked(fp)); 2394 2395 ASSERT_EQ(fileno(fp), fileno_unlocked(fp)); 2396 2397 ASSERT_NE(EOF, putc_unlocked('a', fp)); 2398 ASSERT_NE(EOF, putc('b', fp)); 2399 ASSERT_NE(EOF, fputc_unlocked('c', fp)); 2400 ASSERT_NE(EOF, fputc('d', fp)); 2401 2402 rewind(fp); 2403 ASSERT_EQ('a', getc_unlocked(fp)); 2404 ASSERT_EQ('b', getc(fp)); 2405 ASSERT_EQ('c', fgetc_unlocked(fp)); 2406 ASSERT_EQ('d', fgetc(fp)); 2407 2408 rewind(fp); 2409 ASSERT_EQ(2U, fwrite_unlocked("AB", 1, 2, fp)); 2410 ASSERT_EQ(2U, fwrite("CD", 1, 2, fp)); 2411 ASSERT_EQ(0, fflush_unlocked(fp)); 2412 2413 rewind(fp); 2414 char buf[BUFSIZ] = {}; 2415 ASSERT_EQ(2U, fread_unlocked(&buf[0], 1, 2, fp)); 2416 ASSERT_EQ(2U, fread(&buf[2], 1, 2, fp)); 2417 ASSERT_STREQ("ABCD", buf); 2418 2419 rewind(fp); 2420 ASSERT_NE(EOF, fputs("hello ", fp)); 2421 ASSERT_NE(EOF, fputs_unlocked("world", fp)); 2422 ASSERT_NE(EOF, fputc('\n', fp)); 2423 2424 rewind(fp); 2425 ASSERT_TRUE(fgets_unlocked(buf, sizeof(buf), fp) != nullptr); 2426 ASSERT_STREQ("hello world\n", buf); 2427 2428 ASSERT_EQ(0, fclose(fp)); 2429 } 2430 2431 TEST(STDIO_TEST, fseek_64bit) { 2432 TemporaryFile tf; 2433 FILE* fp = fopen64(tf.filename, "w+"); 2434 ASSERT_TRUE(fp != nullptr); 2435 ASSERT_EQ(0, fseeko64(fp, 0x2'0000'0000, SEEK_SET)); 2436 ASSERT_EQ(0x2'0000'0000, ftello64(fp)); 2437 ASSERT_EQ(0, fseeko64(fp, 0x1'0000'0000, SEEK_CUR)); 2438 ASSERT_EQ(0x3'0000'0000, ftello64(fp)); 2439 ASSERT_EQ(0, fclose(fp)); 2440 } 2441 2442 // POSIX requires that fseek/fseeko fail with EOVERFLOW if the new file offset 2443 // isn't representable in long/off_t. 2444 TEST(STDIO_TEST, fseek_overflow_32bit) { 2445 TemporaryFile tf; 2446 FILE* fp = fopen64(tf.filename, "w+"); 2447 ASSERT_EQ(0, ftruncate64(fileno(fp), 0x2'0000'0000)); 2448 2449 // Bionic implements overflow checking for SEEK_CUR, but glibc doesn't. 2450 #if defined(__BIONIC__) && !defined(__LP64__) 2451 ASSERT_EQ(0, fseek(fp, 0x7fff'ffff, SEEK_SET)); 2452 ASSERT_EQ(-1, fseek(fp, 1, SEEK_CUR)); 2453 ASSERT_EQ(EOVERFLOW, errno); 2454 #endif 2455 2456 // Neither Bionic nor glibc implement the overflow checking for SEEK_END. 2457 // (Aside: FreeBSD's libc is an example of a libc that checks both SEEK_CUR 2458 // and SEEK_END -- many C libraries check neither.) 2459 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 2460 ASSERT_EQ(0x2'0000'0000, ftello64(fp)); 2461 2462 fclose(fp); 2463 } 2464