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