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