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 <vector> 31 32 #include "BionicDeathTest.h" 33 #include "TemporaryFile.h" 34 #include "utils.h" 35 36 #if defined(NOFORTIFY) 37 #define STDIO_TEST stdio_nofortify 38 #define STDIO_DEATHTEST stdio_nofortify_DeathTest 39 #else 40 #define STDIO_TEST stdio 41 #define STDIO_DEATHTEST stdio_DeathTest 42 #endif 43 44 class stdio_DeathTest : public BionicDeathTest {}; 45 class stdio_nofortify_DeathTest : public BionicDeathTest {}; 46 47 static void AssertFileIs(FILE* fp, const char* expected, bool is_fmemopen = false) { 48 rewind(fp); 49 50 char line[1024]; 51 memset(line, 0xff, sizeof(line)); 52 ASSERT_EQ(line, fgets(line, sizeof(line), fp)); 53 ASSERT_STREQ(expected, line); 54 55 if (is_fmemopen) { 56 // fmemopen appends a trailing NUL byte, which probably shouldn't show up as an 57 // extra empty line, but does on every C library I tested... 58 ASSERT_EQ(line, fgets(line, sizeof(line), fp)); 59 ASSERT_STREQ("", line); 60 } 61 62 // Make sure there isn't anything else in the file. 63 ASSERT_EQ(nullptr, fgets(line, sizeof(line), fp)) << "junk at end of file: " << line; 64 } 65 66 TEST(STDIO_TEST, flockfile_18208568_stderr) { 67 // Check that we have a _recursive_ mutex for flockfile. 68 flockfile(stderr); 69 feof(stderr); // We don't care about the result, but this needs to take the lock. 70 funlockfile(stderr); 71 } 72 73 TEST(STDIO_TEST, flockfile_18208568_regular) { 74 // We never had a bug for streams other than stdin/stdout/stderr, but test anyway. 75 FILE* fp = fopen("/dev/null", "w"); 76 ASSERT_TRUE(fp != NULL); 77 flockfile(fp); 78 feof(fp); 79 funlockfile(fp); 80 fclose(fp); 81 } 82 83 TEST(STDIO_TEST, tmpfile_fileno_fprintf_rewind_fgets) { 84 FILE* fp = tmpfile(); 85 ASSERT_TRUE(fp != NULL); 86 87 int fd = fileno(fp); 88 ASSERT_NE(fd, -1); 89 90 struct stat sb; 91 int rc = fstat(fd, &sb); 92 ASSERT_NE(rc, -1); 93 ASSERT_EQ(sb.st_mode & 0777, 0600U); 94 95 rc = fprintf(fp, "hello\n"); 96 ASSERT_EQ(rc, 6); 97 98 AssertFileIs(fp, "hello\n"); 99 fclose(fp); 100 } 101 102 TEST(STDIO_TEST, tmpfile64) { 103 FILE* fp = tmpfile64(); 104 ASSERT_TRUE(fp != nullptr); 105 fclose(fp); 106 } 107 108 TEST(STDIO_TEST, dprintf) { 109 TemporaryFile tf; 110 111 int rc = dprintf(tf.fd, "hello\n"); 112 ASSERT_EQ(rc, 6); 113 114 lseek(tf.fd, 0, SEEK_SET); 115 FILE* tfile = fdopen(tf.fd, "r"); 116 ASSERT_TRUE(tfile != NULL); 117 118 AssertFileIs(tfile, "hello\n"); 119 fclose(tfile); 120 } 121 122 TEST(STDIO_TEST, getdelim) { 123 FILE* fp = tmpfile(); 124 ASSERT_TRUE(fp != NULL); 125 126 const char* line_written = "This is a test"; 127 int rc = fprintf(fp, "%s", line_written); 128 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 129 130 rewind(fp); 131 132 char* word_read = NULL; 133 size_t allocated_length = 0; 134 135 const char* expected[] = { "This ", " ", "is ", "a ", "test" }; 136 for (size_t i = 0; i < 5; ++i) { 137 ASSERT_FALSE(feof(fp)); 138 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), static_cast<int>(strlen(expected[i]))); 139 ASSERT_GE(allocated_length, strlen(expected[i])); 140 ASSERT_STREQ(expected[i], word_read); 141 } 142 // The last read should have set the end-of-file indicator for the stream. 143 ASSERT_TRUE(feof(fp)); 144 clearerr(fp); 145 146 // getdelim returns -1 but doesn't set errno if we're already at EOF. 147 // It should set the end-of-file indicator for the stream, though. 148 errno = 0; 149 ASSERT_EQ(getdelim(&word_read, &allocated_length, ' ', fp), -1); 150 ASSERT_EQ(0, errno); 151 ASSERT_TRUE(feof(fp)); 152 153 free(word_read); 154 fclose(fp); 155 } 156 157 TEST(STDIO_TEST, getdelim_invalid) { 158 FILE* fp = tmpfile(); 159 ASSERT_TRUE(fp != NULL); 160 161 char* buffer = NULL; 162 size_t buffer_length = 0; 163 164 // The first argument can't be NULL. 165 errno = 0; 166 ASSERT_EQ(getdelim(NULL, &buffer_length, ' ', fp), -1); 167 ASSERT_EQ(EINVAL, errno); 168 169 // The second argument can't be NULL. 170 errno = 0; 171 ASSERT_EQ(getdelim(&buffer, NULL, ' ', fp), -1); 172 ASSERT_EQ(EINVAL, errno); 173 174 // The underlying fd can't be closed. 175 ASSERT_EQ(0, close(fileno(fp))); 176 errno = 0; 177 ASSERT_EQ(getdelim(&buffer, &buffer_length, ' ', fp), -1); 178 ASSERT_EQ(EBADF, errno); 179 fclose(fp); 180 } 181 182 TEST(STDIO_TEST, getdelim_directory) { 183 FILE* fp = fopen("/proc", "r"); 184 ASSERT_TRUE(fp != NULL); 185 char* word_read; 186 size_t allocated_length; 187 ASSERT_EQ(-1, getdelim(&word_read, &allocated_length, ' ', fp)); 188 fclose(fp); 189 } 190 191 TEST(STDIO_TEST, getline) { 192 FILE* fp = tmpfile(); 193 ASSERT_TRUE(fp != NULL); 194 195 const char* line_written = "This is a test for getline\n"; 196 const size_t line_count = 5; 197 198 for (size_t i = 0; i < line_count; ++i) { 199 int rc = fprintf(fp, "%s", line_written); 200 ASSERT_EQ(rc, static_cast<int>(strlen(line_written))); 201 } 202 203 rewind(fp); 204 205 char* line_read = NULL; 206 size_t allocated_length = 0; 207 208 size_t read_line_count = 0; 209 ssize_t read_char_count; 210 while ((read_char_count = getline(&line_read, &allocated_length, fp)) != -1) { 211 ASSERT_EQ(read_char_count, static_cast<int>(strlen(line_written))); 212 ASSERT_GE(allocated_length, strlen(line_written)); 213 ASSERT_STREQ(line_written, line_read); 214 ++read_line_count; 215 } 216 ASSERT_EQ(read_line_count, line_count); 217 218 // The last read should have set the end-of-file indicator for the stream. 219 ASSERT_TRUE(feof(fp)); 220 clearerr(fp); 221 222 // getline returns -1 but doesn't set errno if we're already at EOF. 223 // It should set the end-of-file indicator for the stream, though. 224 errno = 0; 225 ASSERT_EQ(getline(&line_read, &allocated_length, fp), -1); 226 ASSERT_EQ(0, errno); 227 ASSERT_TRUE(feof(fp)); 228 229 free(line_read); 230 fclose(fp); 231 } 232 233 TEST(STDIO_TEST, getline_invalid) { 234 FILE* fp = tmpfile(); 235 ASSERT_TRUE(fp != NULL); 236 237 char* buffer = NULL; 238 size_t buffer_length = 0; 239 240 // The first argument can't be NULL. 241 errno = 0; 242 ASSERT_EQ(getline(NULL, &buffer_length, fp), -1); 243 ASSERT_EQ(EINVAL, errno); 244 245 // The second argument can't be NULL. 246 errno = 0; 247 ASSERT_EQ(getline(&buffer, NULL, fp), -1); 248 ASSERT_EQ(EINVAL, errno); 249 250 // The underlying fd can't be closed. 251 ASSERT_EQ(0, close(fileno(fp))); 252 errno = 0; 253 ASSERT_EQ(getline(&buffer, &buffer_length, fp), -1); 254 ASSERT_EQ(EBADF, errno); 255 fclose(fp); 256 } 257 258 TEST(STDIO_TEST, printf_ssize_t) { 259 // http://b/8253769 260 ASSERT_EQ(sizeof(ssize_t), sizeof(long int)); 261 ASSERT_EQ(sizeof(ssize_t), sizeof(size_t)); 262 // For our 32-bit ABI, we had a ssize_t definition that confuses GCC into saying: 263 // error: format '%zd' expects argument of type 'signed size_t', 264 // but argument 4 has type 'ssize_t {aka long int}' [-Werror=format] 265 ssize_t v = 1; 266 char buf[32]; 267 snprintf(buf, sizeof(buf), "%zd", v); 268 } 269 270 // https://code.google.com/p/android/issues/detail?id=64886 271 TEST(STDIO_TEST, snprintf_a) { 272 char buf[BUFSIZ]; 273 EXPECT_EQ(23, snprintf(buf, sizeof(buf), "<%a>", 9990.235)); 274 EXPECT_STREQ("<0x1.3831e147ae148p+13>", buf); 275 } 276 277 TEST(STDIO_TEST, snprintf_lc) { 278 char buf[BUFSIZ]; 279 wint_t wc = L'a'; 280 EXPECT_EQ(3, snprintf(buf, sizeof(buf), "<%lc>", wc)); 281 EXPECT_STREQ("<a>", buf); 282 } 283 284 TEST(STDIO_TEST, snprintf_ls) { 285 char buf[BUFSIZ]; 286 wchar_t* ws = NULL; 287 EXPECT_EQ(8, snprintf(buf, sizeof(buf), "<%ls>", ws)); 288 EXPECT_STREQ("<(null)>", buf); 289 290 wchar_t chars[] = { L'h', L'i', 0 }; 291 ws = chars; 292 EXPECT_EQ(4, snprintf(buf, sizeof(buf), "<%ls>", ws)); 293 EXPECT_STREQ("<hi>", buf); 294 } 295 296 TEST(STDIO_TEST, snprintf_n) { 297 #if defined(__BIONIC__) 298 // http://b/14492135 299 char buf[32]; 300 int i = 1234; 301 EXPECT_EQ(5, snprintf(buf, sizeof(buf), "a %n b", &i)); 302 EXPECT_EQ(1234, i); 303 EXPECT_STREQ("a n b", buf); 304 #else 305 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n"; 306 #endif 307 } 308 309 TEST(STDIO_TEST, snprintf_smoke) { 310 char buf[BUFSIZ]; 311 312 snprintf(buf, sizeof(buf), "a"); 313 EXPECT_STREQ("a", buf); 314 315 snprintf(buf, sizeof(buf), "%%"); 316 EXPECT_STREQ("%", buf); 317 318 snprintf(buf, sizeof(buf), "01234"); 319 EXPECT_STREQ("01234", buf); 320 321 snprintf(buf, sizeof(buf), "a%sb", "01234"); 322 EXPECT_STREQ("a01234b", buf); 323 324 char* s = NULL; 325 snprintf(buf, sizeof(buf), "a%sb", s); 326 EXPECT_STREQ("a(null)b", buf); 327 328 snprintf(buf, sizeof(buf), "aa%scc", "bb"); 329 EXPECT_STREQ("aabbcc", buf); 330 331 snprintf(buf, sizeof(buf), "a%cc", 'b'); 332 EXPECT_STREQ("abc", buf); 333 334 snprintf(buf, sizeof(buf), "a%db", 1234); 335 EXPECT_STREQ("a1234b", buf); 336 337 snprintf(buf, sizeof(buf), "a%db", -8123); 338 EXPECT_STREQ("a-8123b", buf); 339 340 snprintf(buf, sizeof(buf), "a%hdb", static_cast<short>(0x7fff0010)); 341 EXPECT_STREQ("a16b", buf); 342 343 snprintf(buf, sizeof(buf), "a%hhdb", static_cast<char>(0x7fffff10)); 344 EXPECT_STREQ("a16b", buf); 345 346 snprintf(buf, sizeof(buf), "a%lldb", 0x1000000000LL); 347 EXPECT_STREQ("a68719476736b", buf); 348 349 snprintf(buf, sizeof(buf), "a%ldb", 70000L); 350 EXPECT_STREQ("a70000b", buf); 351 352 snprintf(buf, sizeof(buf), "a%pb", reinterpret_cast<void*>(0xb0001234)); 353 EXPECT_STREQ("a0xb0001234b", buf); 354 355 snprintf(buf, sizeof(buf), "a%xz", 0x12ab); 356 EXPECT_STREQ("a12abz", buf); 357 358 snprintf(buf, sizeof(buf), "a%Xz", 0x12ab); 359 EXPECT_STREQ("a12ABz", buf); 360 361 snprintf(buf, sizeof(buf), "a%08xz", 0x123456); 362 EXPECT_STREQ("a00123456z", buf); 363 364 snprintf(buf, sizeof(buf), "a%5dz", 1234); 365 EXPECT_STREQ("a 1234z", buf); 366 367 snprintf(buf, sizeof(buf), "a%05dz", 1234); 368 EXPECT_STREQ("a01234z", buf); 369 370 snprintf(buf, sizeof(buf), "a%8dz", 1234); 371 EXPECT_STREQ("a 1234z", buf); 372 373 snprintf(buf, sizeof(buf), "a%-8dz", 1234); 374 EXPECT_STREQ("a1234 z", buf); 375 376 snprintf(buf, sizeof(buf), "A%-11sZ", "abcdef"); 377 EXPECT_STREQ("Aabcdef Z", buf); 378 379 snprintf(buf, sizeof(buf), "A%s:%dZ", "hello", 1234); 380 EXPECT_STREQ("Ahello:1234Z", buf); 381 382 snprintf(buf, sizeof(buf), "a%03d:%d:%02dz", 5, 5, 5); 383 EXPECT_STREQ("a005:5:05z", buf); 384 385 void* p = NULL; 386 snprintf(buf, sizeof(buf), "a%d,%pz", 5, p); 387 #if defined(__BIONIC__) 388 EXPECT_STREQ("a5,0x0z", buf); 389 #else // __BIONIC__ 390 EXPECT_STREQ("a5,(nil)z", buf); 391 #endif // __BIONIC__ 392 393 snprintf(buf, sizeof(buf), "a%lld,%d,%d,%dz", 0x1000000000LL, 6, 7, 8); 394 EXPECT_STREQ("a68719476736,6,7,8z", buf); 395 396 snprintf(buf, sizeof(buf), "a_%f_b", 1.23f); 397 EXPECT_STREQ("a_1.230000_b", buf); 398 399 snprintf(buf, sizeof(buf), "a_%g_b", 3.14); 400 EXPECT_STREQ("a_3.14_b", buf); 401 402 snprintf(buf, sizeof(buf), "%1$s %1$s", "print_me_twice"); 403 EXPECT_STREQ("print_me_twice print_me_twice", buf); 404 } 405 406 template <typename T> 407 static void CheckInfNan(int snprintf_fn(T*, size_t, const T*, ...), 408 int sscanf_fn(const T*, const T*, ...), 409 const T* fmt_string, const T* fmt, const T* fmt_plus, 410 const T* minus_inf, const T* inf_, const T* plus_inf, 411 const T* minus_nan, const T* nan_, const T* plus_nan) { 412 T buf[BUFSIZ]; 413 float f; 414 415 // NaN. 416 417 snprintf_fn(buf, sizeof(buf), fmt, nanf("")); 418 EXPECT_STREQ(nan_, buf) << fmt; 419 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 420 EXPECT_TRUE(isnan(f)); 421 422 snprintf_fn(buf, sizeof(buf), fmt, -nanf("")); 423 EXPECT_STREQ(minus_nan, buf) << fmt; 424 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 425 EXPECT_TRUE(isnan(f)); 426 427 snprintf_fn(buf, sizeof(buf), fmt_plus, nanf("")); 428 EXPECT_STREQ(plus_nan, buf) << fmt_plus; 429 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 430 EXPECT_TRUE(isnan(f)); 431 432 snprintf_fn(buf, sizeof(buf), fmt_plus, -nanf("")); 433 EXPECT_STREQ(minus_nan, buf) << fmt_plus; 434 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 435 EXPECT_TRUE(isnan(f)); 436 437 // Inf. 438 439 snprintf_fn(buf, sizeof(buf), fmt, HUGE_VALF); 440 EXPECT_STREQ(inf_, buf) << fmt; 441 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 442 EXPECT_EQ(HUGE_VALF, f); 443 444 snprintf_fn(buf, sizeof(buf), fmt, -HUGE_VALF); 445 EXPECT_STREQ(minus_inf, buf) << fmt; 446 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 447 EXPECT_EQ(-HUGE_VALF, f); 448 449 snprintf_fn(buf, sizeof(buf), fmt_plus, HUGE_VALF); 450 EXPECT_STREQ(plus_inf, buf) << fmt_plus; 451 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 452 EXPECT_EQ(HUGE_VALF, f); 453 454 snprintf_fn(buf, sizeof(buf), fmt_plus, -HUGE_VALF); 455 EXPECT_STREQ(minus_inf, buf) << fmt_plus; 456 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)); 457 EXPECT_EQ(-HUGE_VALF, f); 458 459 // Check case-insensitivity. 460 snprintf_fn(buf, sizeof(buf), fmt_string, "[InFiNiTy]"); 461 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)) << buf; 462 EXPECT_EQ(HUGE_VALF, f); 463 snprintf_fn(buf, sizeof(buf), fmt_string, "[NaN]"); 464 EXPECT_EQ(1, sscanf_fn(buf, fmt, &f)) << buf; 465 EXPECT_TRUE(isnan(f)); 466 } 467 468 TEST(STDIO_TEST, snprintf_sscanf_inf_nan) { 469 CheckInfNan(snprintf, sscanf, "%s", 470 "[%a]", "[%+a]", 471 "[-inf]", "[inf]", "[+inf]", 472 "[-nan]", "[nan]", "[+nan]"); 473 CheckInfNan(snprintf, sscanf, "%s", 474 "[%A]", "[%+A]", 475 "[-INF]", "[INF]", "[+INF]", 476 "[-NAN]", "[NAN]", "[+NAN]"); 477 CheckInfNan(snprintf, sscanf, "%s", 478 "[%e]", "[%+e]", 479 "[-inf]", "[inf]", "[+inf]", 480 "[-nan]", "[nan]", "[+nan]"); 481 CheckInfNan(snprintf, sscanf, "%s", 482 "[%E]", "[%+E]", 483 "[-INF]", "[INF]", "[+INF]", 484 "[-NAN]", "[NAN]", "[+NAN]"); 485 CheckInfNan(snprintf, sscanf, "%s", 486 "[%f]", "[%+f]", 487 "[-inf]", "[inf]", "[+inf]", 488 "[-nan]", "[nan]", "[+nan]"); 489 CheckInfNan(snprintf, sscanf, "%s", 490 "[%F]", "[%+F]", 491 "[-INF]", "[INF]", "[+INF]", 492 "[-NAN]", "[NAN]", "[+NAN]"); 493 CheckInfNan(snprintf, sscanf, "%s", 494 "[%g]", "[%+g]", 495 "[-inf]", "[inf]", "[+inf]", 496 "[-nan]", "[nan]", "[+nan]"); 497 CheckInfNan(snprintf, sscanf, "%s", 498 "[%G]", "[%+G]", 499 "[-INF]", "[INF]", "[+INF]", 500 "[-NAN]", "[NAN]", "[+NAN]"); 501 } 502 503 TEST(STDIO_TEST, swprintf_swscanf_inf_nan) { 504 CheckInfNan(swprintf, swscanf, L"%s", 505 L"[%a]", L"[%+a]", 506 L"[-inf]", L"[inf]", L"[+inf]", 507 L"[-nan]", L"[nan]", L"[+nan]"); 508 CheckInfNan(swprintf, swscanf, L"%s", 509 L"[%A]", L"[%+A]", 510 L"[-INF]", L"[INF]", L"[+INF]", 511 L"[-NAN]", L"[NAN]", L"[+NAN]"); 512 CheckInfNan(swprintf, swscanf, L"%s", 513 L"[%e]", L"[%+e]", 514 L"[-inf]", L"[inf]", L"[+inf]", 515 L"[-nan]", L"[nan]", L"[+nan]"); 516 CheckInfNan(swprintf, swscanf, L"%s", 517 L"[%E]", L"[%+E]", 518 L"[-INF]", L"[INF]", L"[+INF]", 519 L"[-NAN]", L"[NAN]", L"[+NAN]"); 520 CheckInfNan(swprintf, swscanf, L"%s", 521 L"[%f]", L"[%+f]", 522 L"[-inf]", L"[inf]", L"[+inf]", 523 L"[-nan]", L"[nan]", L"[+nan]"); 524 CheckInfNan(swprintf, swscanf, L"%s", 525 L"[%F]", L"[%+F]", 526 L"[-INF]", L"[INF]", L"[+INF]", 527 L"[-NAN]", L"[NAN]", L"[+NAN]"); 528 CheckInfNan(swprintf, swscanf, L"%s", 529 L"[%g]", L"[%+g]", 530 L"[-inf]", L"[inf]", L"[+inf]", 531 L"[-nan]", L"[nan]", L"[+nan]"); 532 CheckInfNan(swprintf, swscanf, L"%s", 533 L"[%G]", L"[%+G]", 534 L"[-INF]", L"[INF]", L"[+INF]", 535 L"[-NAN]", L"[NAN]", L"[+NAN]"); 536 } 537 538 TEST(STDIO_TEST, snprintf_d_INT_MAX) { 539 char buf[BUFSIZ]; 540 snprintf(buf, sizeof(buf), "%d", INT_MAX); 541 EXPECT_STREQ("2147483647", buf); 542 } 543 544 TEST(STDIO_TEST, snprintf_d_INT_MIN) { 545 char buf[BUFSIZ]; 546 snprintf(buf, sizeof(buf), "%d", INT_MIN); 547 EXPECT_STREQ("-2147483648", buf); 548 } 549 550 TEST(STDIO_TEST, snprintf_ld_LONG_MAX) { 551 char buf[BUFSIZ]; 552 snprintf(buf, sizeof(buf), "%ld", LONG_MAX); 553 #if defined(__LP64__) 554 EXPECT_STREQ("9223372036854775807", buf); 555 #else 556 EXPECT_STREQ("2147483647", buf); 557 #endif 558 } 559 560 TEST(STDIO_TEST, snprintf_ld_LONG_MIN) { 561 char buf[BUFSIZ]; 562 snprintf(buf, sizeof(buf), "%ld", LONG_MIN); 563 #if defined(__LP64__) 564 EXPECT_STREQ("-9223372036854775808", buf); 565 #else 566 EXPECT_STREQ("-2147483648", buf); 567 #endif 568 } 569 570 TEST(STDIO_TEST, snprintf_lld_LLONG_MAX) { 571 char buf[BUFSIZ]; 572 snprintf(buf, sizeof(buf), "%lld", LLONG_MAX); 573 EXPECT_STREQ("9223372036854775807", buf); 574 } 575 576 TEST(STDIO_TEST, snprintf_lld_LLONG_MIN) { 577 char buf[BUFSIZ]; 578 snprintf(buf, sizeof(buf), "%lld", LLONG_MIN); 579 EXPECT_STREQ("-9223372036854775808", buf); 580 } 581 582 TEST(STDIO_TEST, snprintf_e) { 583 char buf[BUFSIZ]; 584 585 snprintf(buf, sizeof(buf), "%e", 1.5); 586 EXPECT_STREQ("1.500000e+00", buf); 587 588 snprintf(buf, sizeof(buf), "%Le", 1.5l); 589 EXPECT_STREQ("1.500000e+00", buf); 590 } 591 592 TEST(STDIO_TEST, snprintf_negative_zero_5084292) { 593 char buf[BUFSIZ]; 594 595 snprintf(buf, sizeof(buf), "%e", -0.0); 596 EXPECT_STREQ("-0.000000e+00", buf); 597 snprintf(buf, sizeof(buf), "%E", -0.0); 598 EXPECT_STREQ("-0.000000E+00", buf); 599 snprintf(buf, sizeof(buf), "%f", -0.0); 600 EXPECT_STREQ("-0.000000", buf); 601 snprintf(buf, sizeof(buf), "%F", -0.0); 602 EXPECT_STREQ("-0.000000", buf); 603 snprintf(buf, sizeof(buf), "%g", -0.0); 604 EXPECT_STREQ("-0", buf); 605 snprintf(buf, sizeof(buf), "%G", -0.0); 606 EXPECT_STREQ("-0", buf); 607 snprintf(buf, sizeof(buf), "%a", -0.0); 608 EXPECT_STREQ("-0x0p+0", buf); 609 snprintf(buf, sizeof(buf), "%A", -0.0); 610 EXPECT_STREQ("-0X0P+0", buf); 611 } 612 613 TEST(STDIO_TEST, snprintf_utf8_15439554) { 614 locale_t cloc = newlocale(LC_ALL, "C.UTF-8", 0); 615 locale_t old_locale = uselocale(cloc); 616 617 // http://b/15439554 618 char buf[BUFSIZ]; 619 620 // 1-byte character. 621 snprintf(buf, sizeof(buf), "%dx%d", 1, 2); 622 EXPECT_STREQ("1x2", buf); 623 // 2-byte character. 624 snprintf(buf, sizeof(buf), "%d\xc2\xa2%d", 1, 2); 625 EXPECT_STREQ("12", buf); 626 // 3-byte character. 627 snprintf(buf, sizeof(buf), "%d\xe2\x82\xac%d", 1, 2); 628 EXPECT_STREQ("12", buf); 629 // 4-byte character. 630 snprintf(buf, sizeof(buf), "%d\xf0\xa4\xad\xa2%d", 1, 2); 631 EXPECT_STREQ("12", buf); 632 633 uselocale(old_locale); 634 freelocale(cloc); 635 } 636 637 static void* snprintf_small_stack_fn(void*) { 638 // Make life (realistically) hard for ourselves by allocating our own buffer for the result. 639 char buf[PATH_MAX]; 640 snprintf(buf, sizeof(buf), "/proc/%d", getpid()); 641 return nullptr; 642 } 643 644 TEST(STDIO_TEST, snprintf_small_stack) { 645 // Is it safe to call snprintf on a thread with a small stack? 646 // (The snprintf implementation puts some pretty large buffers on the stack.) 647 pthread_attr_t a; 648 ASSERT_EQ(0, pthread_attr_init(&a)); 649 ASSERT_EQ(0, pthread_attr_setstacksize(&a, PTHREAD_STACK_MIN)); 650 651 pthread_t t; 652 ASSERT_EQ(0, pthread_create(&t, &a, snprintf_small_stack_fn, nullptr)); 653 ASSERT_EQ(0, pthread_join(t, nullptr)); 654 } 655 656 TEST(STDIO_TEST, snprintf_asterisk_overflow) { 657 char buf[128]; 658 ASSERT_EQ(5, snprintf(buf, sizeof(buf), "%.*s%c", 4, "hello world", '!')); 659 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX/2, "hello world", '!')); 660 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX-1, "hello world", '!')); 661 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", INT_MAX, "hello world", '!')); 662 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.*s%c", -1, "hello world", '!')); 663 664 // INT_MAX-1, INT_MAX, INT_MAX+1. 665 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483646s%c", "hello world", '!')); 666 ASSERT_EQ(12, snprintf(buf, sizeof(buf), "%.2147483647s%c", "hello world", '!')); 667 ASSERT_EQ(-1, snprintf(buf, sizeof(buf), "%.2147483648s%c", "hello world", '!')); 668 ASSERT_EQ(ENOMEM, errno); 669 } 670 671 TEST(STDIO_TEST, fprintf) { 672 TemporaryFile tf; 673 674 FILE* tfile = fdopen(tf.fd, "r+"); 675 ASSERT_TRUE(tfile != nullptr); 676 677 ASSERT_EQ(7, fprintf(tfile, "%d %s", 123, "abc")); 678 AssertFileIs(tfile, "123 abc"); 679 fclose(tfile); 680 } 681 682 TEST(STDIO_TEST, fprintf_failures_7229520) { 683 // http://b/7229520 684 FILE* fp; 685 686 // Unbuffered case where the fprintf(3) itself fails. 687 ASSERT_NE(nullptr, fp = tmpfile()); 688 setbuf(fp, NULL); 689 ASSERT_EQ(4, fprintf(fp, "epic")); 690 ASSERT_EQ(0, close(fileno(fp))); 691 ASSERT_EQ(-1, fprintf(fp, "fail")); 692 ASSERT_EQ(-1, fclose(fp)); 693 694 // Buffered case where we won't notice until the fclose(3). 695 // It's likely this is what was actually seen in http://b/7229520, 696 // and that expecting fprintf to fail is setting yourself up for 697 // disappointment. Remember to check fclose(3)'s return value, kids! 698 ASSERT_NE(nullptr, fp = tmpfile()); 699 ASSERT_EQ(4, fprintf(fp, "epic")); 700 ASSERT_EQ(0, close(fileno(fp))); 701 ASSERT_EQ(4, fprintf(fp, "fail")); 702 ASSERT_EQ(-1, fclose(fp)); 703 } 704 705 TEST(STDIO_TEST, popen) { 706 FILE* fp = popen("cat /proc/version", "r"); 707 ASSERT_TRUE(fp != NULL); 708 709 char buf[16]; 710 char* s = fgets(buf, sizeof(buf), fp); 711 buf[13] = '\0'; 712 ASSERT_STREQ("Linux version", s); 713 714 ASSERT_EQ(0, pclose(fp)); 715 } 716 717 TEST(STDIO_TEST, getc) { 718 FILE* fp = fopen("/proc/version", "r"); 719 ASSERT_TRUE(fp != NULL); 720 ASSERT_EQ('L', getc(fp)); 721 ASSERT_EQ('i', getc(fp)); 722 ASSERT_EQ('n', getc(fp)); 723 ASSERT_EQ('u', getc(fp)); 724 ASSERT_EQ('x', getc(fp)); 725 fclose(fp); 726 } 727 728 TEST(STDIO_TEST, putc) { 729 FILE* fp = fopen("/proc/version", "r"); 730 ASSERT_TRUE(fp != NULL); 731 ASSERT_EQ(EOF, putc('x', fp)); 732 fclose(fp); 733 } 734 735 TEST(STDIO_TEST, sscanf_swscanf) { 736 struct stuff { 737 char s1[123]; 738 int i1; 739 double d1; 740 float f1; 741 char s2[123]; 742 743 void Check() { 744 ASSERT_STREQ("hello", s1); 745 ASSERT_EQ(123, i1); 746 ASSERT_DOUBLE_EQ(1.23, d1); 747 ASSERT_FLOAT_EQ(9.0f, f1); 748 ASSERT_STREQ("world", s2); 749 } 750 } s; 751 752 memset(&s, 0, sizeof(s)); 753 ASSERT_EQ(5, sscanf(" hello 123 1.23 0x1.2p3 world", 754 "%s %i %lf %f %s", 755 s.s1, &s.i1, &s.d1, &s.f1, s.s2)); 756 s.Check(); 757 758 memset(&s, 0, sizeof(s)); 759 ASSERT_EQ(5, swscanf(L" hello 123 1.23 0x1.2p3 world", 760 L"%s %i %lf %f %s", 761 s.s1, &s.i1, &s.d1, &s.f1, s.s2)); 762 s.Check(); 763 } 764 765 TEST(STDIO_TEST, cantwrite_EBADF) { 766 // If we open a file read-only... 767 FILE* fp = fopen("/proc/version", "r"); 768 769 // ...all attempts to write to that file should return failure. 770 771 // They should also set errno to EBADF. This isn't POSIX, but it's traditional. 772 // glibc gets the wide-character functions wrong. 773 774 errno = 0; 775 EXPECT_EQ(EOF, putc('x', fp)); 776 EXPECT_EQ(EBADF, errno); 777 778 errno = 0; 779 EXPECT_EQ(EOF, fprintf(fp, "hello")); 780 EXPECT_EQ(EBADF, errno); 781 782 errno = 0; 783 EXPECT_EQ(EOF, fwprintf(fp, L"hello")); 784 #if defined(__BIONIC__) 785 EXPECT_EQ(EBADF, errno); 786 #endif 787 788 errno = 0; 789 EXPECT_EQ(0U, fwrite("hello", 1, 2, fp)); 790 EXPECT_EQ(EBADF, errno); 791 792 errno = 0; 793 EXPECT_EQ(EOF, fputs("hello", fp)); 794 EXPECT_EQ(EBADF, errno); 795 796 errno = 0; 797 EXPECT_EQ(WEOF, fputwc(L'x', fp)); 798 #if defined(__BIONIC__) 799 EXPECT_EQ(EBADF, errno); 800 #endif 801 } 802 803 // Tests that we can only have a consistent and correct fpos_t when using 804 // f*pos functions (i.e. fpos doesn't get inside a multi byte character). 805 TEST(STDIO_TEST, consistent_fpos_t) { 806 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 807 uselocale(LC_GLOBAL_LOCALE); 808 809 FILE* fp = tmpfile(); 810 ASSERT_TRUE(fp != NULL); 811 812 wchar_t mb_one_bytes = L'h'; 813 wchar_t mb_two_bytes = 0x00a2; 814 wchar_t mb_three_bytes = 0x20ac; 815 wchar_t mb_four_bytes = 0x24b62; 816 817 // Write to file. 818 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fputwc(mb_one_bytes, fp))); 819 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 820 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 821 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 822 823 rewind(fp); 824 825 // Record each character position. 826 fpos_t pos1; 827 fpos_t pos2; 828 fpos_t pos3; 829 fpos_t pos4; 830 fpos_t pos5; 831 EXPECT_EQ(0, fgetpos(fp, &pos1)); 832 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 833 EXPECT_EQ(0, fgetpos(fp, &pos2)); 834 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 835 EXPECT_EQ(0, fgetpos(fp, &pos3)); 836 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 837 EXPECT_EQ(0, fgetpos(fp, &pos4)); 838 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 839 EXPECT_EQ(0, fgetpos(fp, &pos5)); 840 841 #if defined(__BIONIC__) 842 // Bionic's fpos_t is just an alias for off_t. This is inherited from OpenBSD 843 // upstream. Glibc differs by storing the mbstate_t inside its fpos_t. In 844 // Bionic (and upstream OpenBSD) the mbstate_t is stored inside the FILE 845 // structure. 846 ASSERT_EQ(0, static_cast<off_t>(pos1)); 847 ASSERT_EQ(1, static_cast<off_t>(pos2)); 848 ASSERT_EQ(3, static_cast<off_t>(pos3)); 849 ASSERT_EQ(6, static_cast<off_t>(pos4)); 850 ASSERT_EQ(10, static_cast<off_t>(pos5)); 851 #endif 852 853 // Exercise back and forth movements of the position. 854 ASSERT_EQ(0, fsetpos(fp, &pos2)); 855 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 856 ASSERT_EQ(0, fsetpos(fp, &pos1)); 857 ASSERT_EQ(mb_one_bytes, static_cast<wchar_t>(fgetwc(fp))); 858 ASSERT_EQ(0, fsetpos(fp, &pos4)); 859 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fgetwc(fp))); 860 ASSERT_EQ(0, fsetpos(fp, &pos3)); 861 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fgetwc(fp))); 862 ASSERT_EQ(0, fsetpos(fp, &pos5)); 863 ASSERT_EQ(WEOF, fgetwc(fp)); 864 865 fclose(fp); 866 } 867 868 // Exercise the interaction between fpos and seek. 869 TEST(STDIO_TEST, fpos_t_and_seek) { 870 ASSERT_STREQ("C.UTF-8", setlocale(LC_CTYPE, "C.UTF-8")); 871 uselocale(LC_GLOBAL_LOCALE); 872 873 // In glibc-2.16 fseek doesn't work properly in wide mode 874 // (https://sourceware.org/bugzilla/show_bug.cgi?id=14543). One workaround is 875 // to close and re-open the file. We do it in order to make the test pass 876 // with all glibcs. 877 878 TemporaryFile tf; 879 FILE* fp = fdopen(tf.fd, "w+"); 880 ASSERT_TRUE(fp != NULL); 881 882 wchar_t mb_two_bytes = 0x00a2; 883 wchar_t mb_three_bytes = 0x20ac; 884 wchar_t mb_four_bytes = 0x24b62; 885 886 // Write to file. 887 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fputwc(mb_two_bytes, fp))); 888 ASSERT_EQ(mb_three_bytes, static_cast<wchar_t>(fputwc(mb_three_bytes, fp))); 889 ASSERT_EQ(mb_four_bytes, static_cast<wchar_t>(fputwc(mb_four_bytes, fp))); 890 891 fflush(fp); 892 fclose(fp); 893 894 fp = fopen(tf.filename, "r"); 895 ASSERT_TRUE(fp != NULL); 896 897 // Store a valid position. 898 fpos_t mb_two_bytes_pos; 899 ASSERT_EQ(0, fgetpos(fp, &mb_two_bytes_pos)); 900 901 // Move inside mb_four_bytes with fseek. 902 long offset_inside_mb = 6; 903 ASSERT_EQ(0, fseek(fp, offset_inside_mb, SEEK_SET)); 904 905 // Store the "inside multi byte" position. 906 fpos_t pos_inside_mb; 907 ASSERT_EQ(0, fgetpos(fp, &pos_inside_mb)); 908 #if defined(__BIONIC__) 909 ASSERT_EQ(offset_inside_mb, static_cast<off_t>(pos_inside_mb)); 910 #endif 911 912 // Reading from within a byte should produce an error. 913 ASSERT_EQ(WEOF, fgetwc(fp)); 914 ASSERT_EQ(EILSEQ, errno); 915 916 // Reverting to a valid position should work. 917 ASSERT_EQ(0, fsetpos(fp, &mb_two_bytes_pos)); 918 ASSERT_EQ(mb_two_bytes, static_cast<wchar_t>(fgetwc(fp))); 919 920 // Moving withing a multi byte with fsetpos should work but reading should 921 // produce an error. 922 ASSERT_EQ(0, fsetpos(fp, &pos_inside_mb)); 923 ASSERT_EQ(WEOF, fgetwc(fp)); 924 ASSERT_EQ(EILSEQ, errno); 925 926 fclose(fp); 927 } 928 929 TEST(STDIO_TEST, fmemopen) { 930 char buf[16]; 931 memset(buf, 0, sizeof(buf)); 932 FILE* fp = fmemopen(buf, sizeof(buf), "r+"); 933 ASSERT_EQ('<', fputc('<', fp)); 934 ASSERT_NE(EOF, fputs("abc>\n", fp)); 935 fflush(fp); 936 937 ASSERT_STREQ("<abc>\n", buf); 938 939 AssertFileIs(fp, "<abc>\n", true); 940 fclose(fp); 941 } 942 943 TEST(STDIO_TEST, KNOWN_FAILURE_ON_BIONIC(fmemopen_NULL)) { 944 FILE* fp = fmemopen(nullptr, 128, "r+"); 945 ASSERT_NE(EOF, fputs("xyz\n", fp)); 946 947 AssertFileIs(fp, "xyz\n", true); 948 fclose(fp); 949 } 950 951 TEST(STDIO_TEST, fmemopen_EINVAL) { 952 char buf[16]; 953 954 // Invalid size. 955 errno = 0; 956 ASSERT_EQ(nullptr, fmemopen(buf, 0, "r+")); 957 ASSERT_EQ(EINVAL, errno); 958 959 // No '+' with NULL buffer. 960 errno = 0; 961 ASSERT_EQ(nullptr, fmemopen(nullptr, 0, "r")); 962 ASSERT_EQ(EINVAL, errno); 963 } 964 965 TEST(STDIO_TEST, open_memstream) { 966 char* p = nullptr; 967 size_t size = 0; 968 FILE* fp = open_memstream(&p, &size); 969 ASSERT_NE(EOF, fputs("hello, world!", fp)); 970 fclose(fp); 971 972 ASSERT_STREQ("hello, world!", p); 973 ASSERT_EQ(strlen("hello, world!"), size); 974 free(p); 975 } 976 977 TEST(STDIO_TEST, open_memstream_EINVAL) { 978 #if defined(__BIONIC__) 979 char* p; 980 size_t size; 981 982 // Invalid buffer. 983 errno = 0; 984 ASSERT_EQ(nullptr, open_memstream(nullptr, &size)); 985 ASSERT_EQ(EINVAL, errno); 986 987 // Invalid size. 988 errno = 0; 989 ASSERT_EQ(nullptr, open_memstream(&p, nullptr)); 990 ASSERT_EQ(EINVAL, errno); 991 #else 992 GTEST_LOG_(INFO) << "This test does nothing on glibc.\n"; 993 #endif 994 } 995 996 TEST(STDIO_TEST, fdopen_CLOEXEC) { 997 int fd = open("/proc/version", O_RDONLY); 998 ASSERT_TRUE(fd != -1); 999 1000 // This fd doesn't have O_CLOEXEC... 1001 int flags = fcntl(fd, F_GETFD); 1002 ASSERT_TRUE(flags != -1); 1003 ASSERT_EQ(0, flags & FD_CLOEXEC); 1004 1005 FILE* fp = fdopen(fd, "re"); 1006 ASSERT_TRUE(fp != NULL); 1007 1008 // ...but the new one does. 1009 flags = fcntl(fileno(fp), F_GETFD); 1010 ASSERT_TRUE(flags != -1); 1011 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC); 1012 1013 fclose(fp); 1014 close(fd); 1015 } 1016 1017 TEST(STDIO_TEST, freopen_CLOEXEC) { 1018 FILE* fp = fopen("/proc/version", "r"); 1019 ASSERT_TRUE(fp != NULL); 1020 1021 // This FILE* doesn't have O_CLOEXEC... 1022 int flags = fcntl(fileno(fp), F_GETFD); 1023 ASSERT_TRUE(flags != -1); 1024 ASSERT_EQ(0, flags & FD_CLOEXEC); 1025 1026 fp = freopen("/proc/version", "re", fp); 1027 1028 // ...but the new one does. 1029 flags = fcntl(fileno(fp), F_GETFD); 1030 ASSERT_TRUE(flags != -1); 1031 ASSERT_EQ(FD_CLOEXEC, flags & FD_CLOEXEC); 1032 1033 fclose(fp); 1034 } 1035 1036 TEST(STDIO_TEST, fopen64_freopen64) { 1037 FILE* fp = fopen64("/proc/version", "r"); 1038 ASSERT_TRUE(fp != nullptr); 1039 fp = freopen64("/proc/version", "re", fp); 1040 ASSERT_TRUE(fp != nullptr); 1041 fclose(fp); 1042 } 1043 1044 // https://code.google.com/p/android/issues/detail?id=81155 1045 // http://b/18556607 1046 TEST(STDIO_TEST, fread_unbuffered_pathological_performance) { 1047 FILE* fp = fopen("/dev/zero", "r"); 1048 ASSERT_TRUE(fp != NULL); 1049 1050 // Make this stream unbuffered. 1051 setvbuf(fp, 0, _IONBF, 0); 1052 1053 char buf[65*1024]; 1054 memset(buf, 0xff, sizeof(buf)); 1055 1056 time_t t0 = time(NULL); 1057 for (size_t i = 0; i < 1024; ++i) { 1058 ASSERT_EQ(1U, fread(buf, 64*1024, 1, fp)); 1059 } 1060 time_t t1 = time(NULL); 1061 1062 fclose(fp); 1063 1064 // 1024 64KiB reads should have been very quick. 1065 ASSERT_LE(t1 - t0, 1); 1066 1067 for (size_t i = 0; i < 64*1024; ++i) { 1068 ASSERT_EQ('\0', buf[i]); 1069 } 1070 for (size_t i = 64*1024; i < 65*1024; ++i) { 1071 ASSERT_EQ('\xff', buf[i]); 1072 } 1073 } 1074 1075 TEST(STDIO_TEST, fread_EOF) { 1076 std::string digits("0123456789"); 1077 FILE* fp = fmemopen(&digits[0], digits.size(), "r"); 1078 1079 // Try to read too much, but little enough that it still fits in the FILE's internal buffer. 1080 char buf1[4 * 4]; 1081 memset(buf1, 0, sizeof(buf1)); 1082 ASSERT_EQ(2U, fread(buf1, 4, 4, fp)); 1083 ASSERT_STREQ("0123456789", buf1); 1084 ASSERT_TRUE(feof(fp)); 1085 1086 rewind(fp); 1087 1088 // Try to read way too much so stdio tries to read more direct from the stream. 1089 char buf2[4 * 4096]; 1090 memset(buf2, 0, sizeof(buf2)); 1091 ASSERT_EQ(2U, fread(buf2, 4, 4096, fp)); 1092 ASSERT_STREQ("0123456789", buf2); 1093 ASSERT_TRUE(feof(fp)); 1094 1095 fclose(fp); 1096 } 1097 1098 static void test_fread_from_write_only_stream(size_t n) { 1099 FILE* fp = fopen("/dev/null", "w"); 1100 std::vector<char> buf(n, 0); 1101 errno = 0; 1102 ASSERT_EQ(0U, fread(&buf[0], n, 1, fp)); 1103 ASSERT_EQ(EBADF, errno); 1104 ASSERT_TRUE(ferror(fp)); 1105 ASSERT_FALSE(feof(fp)); 1106 fclose(fp); 1107 } 1108 1109 TEST(STDIO_TEST, fread_from_write_only_stream_slow_path) { 1110 test_fread_from_write_only_stream(1); 1111 } 1112 1113 TEST(STDIO_TEST, fread_from_write_only_stream_fast_path) { 1114 test_fread_from_write_only_stream(64*1024); 1115 } 1116 1117 static void test_fwrite_after_fread(size_t n) { 1118 TemporaryFile tf; 1119 1120 FILE* fp = fdopen(tf.fd, "w+"); 1121 ASSERT_EQ(1U, fwrite("1", 1, 1, fp)); 1122 fflush(fp); 1123 1124 // We've flushed but not rewound, so there's nothing to read. 1125 std::vector<char> buf(n, 0); 1126 ASSERT_EQ(0U, fread(&buf[0], 1, buf.size(), fp)); 1127 ASSERT_TRUE(feof(fp)); 1128 1129 // But hitting EOF doesn't prevent us from writing... 1130 errno = 0; 1131 ASSERT_EQ(1U, fwrite("2", 1, 1, fp)) << strerror(errno); 1132 1133 // And if we rewind, everything's there. 1134 rewind(fp); 1135 ASSERT_EQ(2U, fread(&buf[0], 1, buf.size(), fp)); 1136 ASSERT_EQ('1', buf[0]); 1137 ASSERT_EQ('2', buf[1]); 1138 1139 fclose(fp); 1140 } 1141 1142 TEST(STDIO_TEST, fwrite_after_fread_slow_path) { 1143 test_fwrite_after_fread(16); 1144 } 1145 1146 TEST(STDIO_TEST, fwrite_after_fread_fast_path) { 1147 test_fwrite_after_fread(64*1024); 1148 } 1149 1150 // http://b/19172514 1151 TEST(STDIO_TEST, fread_after_fseek) { 1152 TemporaryFile tf; 1153 1154 FILE* fp = fopen(tf.filename, "w+"); 1155 ASSERT_TRUE(fp != nullptr); 1156 1157 char file_data[12288]; 1158 for (size_t i = 0; i < 12288; i++) { 1159 file_data[i] = i; 1160 } 1161 ASSERT_EQ(12288U, fwrite(file_data, 1, 12288, fp)); 1162 fclose(fp); 1163 1164 fp = fopen(tf.filename, "r"); 1165 ASSERT_TRUE(fp != nullptr); 1166 1167 char buffer[8192]; 1168 size_t cur_location = 0; 1169 // Small read to populate internal buffer. 1170 ASSERT_EQ(100U, fread(buffer, 1, 100, fp)); 1171 ASSERT_EQ(memcmp(file_data, buffer, 100), 0); 1172 1173 cur_location = static_cast<size_t>(ftell(fp)); 1174 // Large read to force reading into the user supplied buffer and bypassing 1175 // the internal buffer. 1176 ASSERT_EQ(8192U, fread(buffer, 1, 8192, fp)); 1177 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 8192), 0); 1178 1179 // Small backwards seek to verify fseek does not reuse the internal buffer. 1180 ASSERT_EQ(0, fseek(fp, -22, SEEK_CUR)) << strerror(errno); 1181 cur_location = static_cast<size_t>(ftell(fp)); 1182 ASSERT_EQ(22U, fread(buffer, 1, 22, fp)); 1183 ASSERT_EQ(memcmp(file_data+cur_location, buffer, 22), 0); 1184 1185 fclose(fp); 1186 } 1187 1188 // https://code.google.com/p/android/issues/detail?id=184847 1189 TEST(STDIO_TEST, fread_EOF_184847) { 1190 TemporaryFile tf; 1191 char buf[6] = {0}; 1192 1193 FILE* fw = fopen(tf.filename, "w"); 1194 ASSERT_TRUE(fw != nullptr); 1195 1196 FILE* fr = fopen(tf.filename, "r"); 1197 ASSERT_TRUE(fr != nullptr); 1198 1199 fwrite("a", 1, 1, fw); 1200 fflush(fw); 1201 ASSERT_EQ(1U, fread(buf, 1, 1, fr)); 1202 ASSERT_STREQ("a", buf); 1203 1204 // 'fr' is now at EOF. 1205 ASSERT_EQ(0U, fread(buf, 1, 1, fr)); 1206 ASSERT_TRUE(feof(fr)); 1207 1208 // Write some more... 1209 fwrite("z", 1, 1, fw); 1210 fflush(fw); 1211 1212 // ...and check that we can read it back. 1213 // (BSD thinks that once a stream has hit EOF, it must always return EOF. SysV disagrees.) 1214 ASSERT_EQ(1U, fread(buf, 1, 1, fr)); 1215 ASSERT_STREQ("z", buf); 1216 1217 // But now we're done. 1218 ASSERT_EQ(0U, fread(buf, 1, 1, fr)); 1219 1220 fclose(fr); 1221 fclose(fw); 1222 } 1223 1224 TEST(STDIO_TEST, fclose_invalidates_fd) { 1225 // The typical error we're trying to help people catch involves accessing 1226 // memory after it's been freed. But we know that stdin/stdout/stderr are 1227 // special and don't get deallocated, so this test uses stdin. 1228 ASSERT_EQ(0, fclose(stdin)); 1229 1230 // Even though using a FILE* after close is undefined behavior, I've closed 1231 // this bug as "WAI" too many times. We shouldn't hand out stale fds, 1232 // especially because they might actually correspond to a real stream. 1233 errno = 0; 1234 ASSERT_EQ(-1, fileno(stdin)); 1235 ASSERT_EQ(EBADF, errno); 1236 } 1237 1238 TEST(STDIO_TEST, fseek_ftell_unseekable) { 1239 #if defined(__BIONIC__) // glibc has fopencookie instead. 1240 auto read_fn = [](void*, char*, int) { return -1; }; 1241 FILE* fp = funopen(nullptr, read_fn, nullptr, nullptr, nullptr); 1242 ASSERT_TRUE(fp != nullptr); 1243 1244 // Check that ftell balks on an unseekable FILE*. 1245 errno = 0; 1246 ASSERT_EQ(-1, ftell(fp)); 1247 ASSERT_EQ(ESPIPE, errno); 1248 1249 // SEEK_CUR is rewritten as SEEK_SET internally... 1250 errno = 0; 1251 ASSERT_EQ(-1, fseek(fp, 0, SEEK_CUR)); 1252 ASSERT_EQ(ESPIPE, errno); 1253 1254 // ...so it's worth testing the direct seek path too. 1255 errno = 0; 1256 ASSERT_EQ(-1, fseek(fp, 0, SEEK_SET)); 1257 ASSERT_EQ(ESPIPE, errno); 1258 1259 fclose(fp); 1260 #else 1261 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 1262 #endif 1263 } 1264 1265 TEST(STDIO_TEST, funopen_EINVAL) { 1266 #if defined(__BIONIC__) 1267 errno = 0; 1268 ASSERT_EQ(nullptr, funopen(nullptr, nullptr, nullptr, nullptr, nullptr)); 1269 ASSERT_EQ(EINVAL, errno); 1270 #else 1271 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 1272 #endif 1273 } 1274 1275 TEST(STDIO_TEST, funopen_seek) { 1276 #if defined(__BIONIC__) 1277 auto read_fn = [](void*, char*, int) { return -1; }; 1278 1279 auto seek_fn = [](void*, fpos_t, int) -> fpos_t { return 0xfedcba12; }; 1280 auto seek64_fn = [](void*, fpos64_t, int) -> fpos64_t { return 0xfedcba12345678; }; 1281 1282 FILE* fp = funopen(nullptr, read_fn, nullptr, seek_fn, nullptr); 1283 ASSERT_TRUE(fp != nullptr); 1284 fpos_t pos; 1285 #if defined(__LP64__) 1286 EXPECT_EQ(0, fgetpos(fp, &pos)) << strerror(errno); 1287 EXPECT_EQ(0xfedcba12LL, pos); 1288 #else 1289 EXPECT_EQ(-1, fgetpos(fp, &pos)) << strerror(errno); 1290 EXPECT_EQ(EOVERFLOW, errno); 1291 #endif 1292 1293 FILE* fp64 = funopen64(nullptr, read_fn, nullptr, seek64_fn, nullptr); 1294 ASSERT_TRUE(fp64 != nullptr); 1295 fpos64_t pos64; 1296 EXPECT_EQ(0, fgetpos64(fp64, &pos64)) << strerror(errno); 1297 EXPECT_EQ(0xfedcba12345678, pos64); 1298 #else 1299 GTEST_LOG_(INFO) << "glibc uses fopencookie instead.\n"; 1300 #endif 1301 } 1302 1303 TEST(STDIO_TEST, lots_of_concurrent_files) { 1304 std::vector<TemporaryFile*> tfs; 1305 std::vector<FILE*> fps; 1306 1307 for (size_t i = 0; i < 256; ++i) { 1308 TemporaryFile* tf = new TemporaryFile; 1309 tfs.push_back(tf); 1310 FILE* fp = fopen(tf->filename, "w+"); 1311 fps.push_back(fp); 1312 fprintf(fp, "hello %zu!\n", i); 1313 fflush(fp); 1314 } 1315 1316 for (size_t i = 0; i < 256; ++i) { 1317 char expected[BUFSIZ]; 1318 snprintf(expected, sizeof(expected), "hello %zu!\n", i); 1319 1320 AssertFileIs(fps[i], expected); 1321 fclose(fps[i]); 1322 delete tfs[i]; 1323 } 1324 } 1325 1326 static void AssertFileOffsetAt(FILE* fp, off64_t offset) { 1327 EXPECT_EQ(offset, ftell(fp)); 1328 EXPECT_EQ(offset, ftello(fp)); 1329 EXPECT_EQ(offset, ftello64(fp)); 1330 fpos_t pos; 1331 fpos64_t pos64; 1332 EXPECT_EQ(0, fgetpos(fp, &pos)); 1333 EXPECT_EQ(0, fgetpos64(fp, &pos64)); 1334 #if defined(__BIONIC__) 1335 EXPECT_EQ(offset, static_cast<off64_t>(pos)); 1336 EXPECT_EQ(offset, static_cast<off64_t>(pos64)); 1337 #else 1338 GTEST_LOG_(INFO) << "glibc's fpos_t is opaque.\n"; 1339 #endif 1340 } 1341 1342 TEST(STDIO_TEST, seek_tell_family_smoke) { 1343 TemporaryFile tf; 1344 FILE* fp = fdopen(tf.fd, "w+"); 1345 1346 // Initially we should be at 0. 1347 AssertFileOffsetAt(fp, 0); 1348 1349 // Seek to offset 8192. 1350 ASSERT_EQ(0, fseek(fp, 8192, SEEK_SET)); 1351 AssertFileOffsetAt(fp, 8192); 1352 fpos_t eight_k_pos; 1353 ASSERT_EQ(0, fgetpos(fp, &eight_k_pos)); 1354 1355 // Seek forward another 8192... 1356 ASSERT_EQ(0, fseek(fp, 8192, SEEK_CUR)); 1357 AssertFileOffsetAt(fp, 8192 + 8192); 1358 fpos64_t sixteen_k_pos64; 1359 ASSERT_EQ(0, fgetpos64(fp, &sixteen_k_pos64)); 1360 1361 // Seek back 8192... 1362 ASSERT_EQ(0, fseek(fp, -8192, SEEK_CUR)); 1363 AssertFileOffsetAt(fp, 8192); 1364 1365 // Since we haven't written anything, the end is also at 0. 1366 ASSERT_EQ(0, fseek(fp, 0, SEEK_END)); 1367 AssertFileOffsetAt(fp, 0); 1368 1369 // Check that our fpos64_t from 16KiB works... 1370 ASSERT_EQ(0, fsetpos64(fp, &sixteen_k_pos64)); 1371 AssertFileOffsetAt(fp, 8192 + 8192); 1372 // ...as does our fpos_t from 8192. 1373 ASSERT_EQ(0, fsetpos(fp, &eight_k_pos)); 1374 AssertFileOffsetAt(fp, 8192); 1375 1376 // Do fseeko and fseeko64 work too? 1377 ASSERT_EQ(0, fseeko(fp, 1234, SEEK_SET)); 1378 AssertFileOffsetAt(fp, 1234); 1379 ASSERT_EQ(0, fseeko64(fp, 5678, SEEK_SET)); 1380 AssertFileOffsetAt(fp, 5678); 1381 1382 fclose(fp); 1383 } 1384 1385 TEST(STDIO_TEST, fseek_fseeko_EINVAL) { 1386 TemporaryFile tf; 1387 FILE* fp = fdopen(tf.fd, "w+"); 1388 1389 // Bad whence. 1390 errno = 0; 1391 ASSERT_EQ(-1, fseek(fp, 0, 123)); 1392 ASSERT_EQ(EINVAL, errno); 1393 errno = 0; 1394 ASSERT_EQ(-1, fseeko(fp, 0, 123)); 1395 ASSERT_EQ(EINVAL, errno); 1396 errno = 0; 1397 ASSERT_EQ(-1, fseeko64(fp, 0, 123)); 1398 ASSERT_EQ(EINVAL, errno); 1399 1400 // Bad offset. 1401 errno = 0; 1402 ASSERT_EQ(-1, fseek(fp, -1, SEEK_SET)); 1403 ASSERT_EQ(EINVAL, errno); 1404 errno = 0; 1405 ASSERT_EQ(-1, fseeko(fp, -1, SEEK_SET)); 1406 ASSERT_EQ(EINVAL, errno); 1407 errno = 0; 1408 ASSERT_EQ(-1, fseeko64(fp, -1, SEEK_SET)); 1409 ASSERT_EQ(EINVAL, errno); 1410 1411 fclose(fp); 1412 } 1413 1414 TEST(STDIO_TEST, ctermid) { 1415 ASSERT_STREQ("/dev/tty", ctermid(nullptr)); 1416 1417 char buf[L_ctermid] = {}; 1418 ASSERT_EQ(buf, ctermid(buf)); 1419 ASSERT_STREQ("/dev/tty", buf); 1420 } 1421 1422 TEST(STDIO_TEST, remove) { 1423 struct stat sb; 1424 1425 TemporaryFile tf; 1426 ASSERT_EQ(0, remove(tf.filename)); 1427 ASSERT_EQ(-1, lstat(tf.filename, &sb)); 1428 ASSERT_EQ(ENOENT, errno); 1429 1430 TemporaryDir td; 1431 ASSERT_EQ(0, remove(td.dirname)); 1432 ASSERT_EQ(-1, lstat(td.dirname, &sb)); 1433 ASSERT_EQ(ENOENT, errno); 1434 1435 errno = 0; 1436 ASSERT_EQ(-1, remove(tf.filename)); 1437 ASSERT_EQ(ENOENT, errno); 1438 1439 errno = 0; 1440 ASSERT_EQ(-1, remove(td.dirname)); 1441 ASSERT_EQ(ENOENT, errno); 1442 } 1443 1444 TEST(STDIO_DEATHTEST, snprintf_30445072_known_buffer_size) { 1445 char buf[16]; 1446 ASSERT_EXIT(snprintf(buf, atol("-1"), "hello"), 1447 testing::KilledBySignal(SIGABRT), 1448 #if defined(NOFORTIFY) 1449 "FORTIFY: vsnprintf: size .* > SSIZE_MAX" 1450 #else 1451 "FORTIFY: vsnprintf: prevented .*-byte write into 16-byte buffer" 1452 #endif 1453 ); 1454 } 1455 1456 TEST(STDIO_DEATHTEST, snprintf_30445072_unknown_buffer_size) { 1457 std::string buf = "world"; 1458 ASSERT_EXIT(snprintf(&buf[0], atol("-1"), "hello"), 1459 testing::KilledBySignal(SIGABRT), 1460 "FORTIFY: vsnprintf: size .* > SSIZE_MAX"); 1461 } 1462 1463 TEST(STDIO_TEST, sprintf_30445072) { 1464 std::string buf = "world"; 1465 sprintf(&buf[0], "hello"); 1466 ASSERT_EQ(buf, "hello"); 1467 } 1468