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