summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2014-08-18 17:28:32 -0700
committerElliott Hughes <enh@google.com>2014-08-28 16:37:09 -0700
commit416d7ddaff0946d480b6aa945a741b3eeaca5569 (patch)
treed3fa6382f7d6d26ab7e3ecb95a715328e5f50b5e /tests
parentf4e721dd519db89c504c8944763811a3df956b32 (diff)
downloadbionic-416d7ddaff0946d480b6aa945a741b3eeaca5569.zip
bionic-416d7ddaff0946d480b6aa945a741b3eeaca5569.tar.gz
bionic-416d7ddaff0946d480b6aa945a741b3eeaca5569.tar.bz2
Add GNU-compatible strerror_r.
We already had the POSIX strerror_r, but some third-party code defines _GNU_SOURCE and expects to get the GNU strerror_r instead. This exposed a bug in the libc internal logging functions where unlike their standard brethren they wouldn't return the number of bytes they'd have liked to have written. Bug: 16243479 Change-Id: I1745752ccbdc569646d34f5071f6df2be066d5f4
Diffstat (limited to 'tests')
-rw-r--r--tests/Android.mk1
-rw-r--r--tests/libc_logging_test.cpp12
-rw-r--r--tests/string_posix_strerror_r_test.cpp57
-rw-r--r--tests/string_test.cpp30
4 files changed, 89 insertions, 11 deletions
diff --git a/tests/Android.mk b/tests/Android.mk
index 5179bfa..26014ac 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -95,6 +95,7 @@ libBionicStandardTests_src_files := \
stdio_ext_test.cpp \
stdlib_test.cpp \
string_test.cpp \
+ string_posix_strerror_r_test.cpp \
strings_test.cpp \
stubs_test.cpp \
sstream_test.cpp \
diff --git a/tests/libc_logging_test.cpp b/tests/libc_logging_test.cpp
index 950161e..d4ceded 100644
--- a/tests/libc_logging_test.cpp
+++ b/tests/libc_logging_test.cpp
@@ -176,3 +176,15 @@ TEST(libc_logging, lld_LLONG_MIN) {
GTEST_LOG_(INFO) << "This test does nothing.\n";
#endif // __BIONIC__
}
+
+TEST(libc_logging, buffer_overrun) {
+#if defined(__BIONIC__)
+ char buf[BUFSIZ];
+ ASSERT_EQ(11, __libc_format_buffer(buf, sizeof(buf), "hello %s", "world"));
+ EXPECT_STREQ("hello world", buf);
+ ASSERT_EQ(11, __libc_format_buffer(buf, 8, "hello %s", "world"));
+ EXPECT_STREQ("hello w", buf);
+#else // __BIONIC__
+ GTEST_LOG_(INFO) << "This test does nothing.\n";
+#endif // __BIONIC__
+}
diff --git a/tests/string_posix_strerror_r_test.cpp b/tests/string_posix_strerror_r_test.cpp
new file mode 100644
index 0000000..09cebfe
--- /dev/null
+++ b/tests/string_posix_strerror_r_test.cpp
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#undef _GNU_SOURCE
+
+// Old versions of glibc (like our current host prebuilt sysroot one) have
+// headers that don't work if you #undef _GNU_SOURCE, which makes it
+// impossible to build this test.
+#include <features.h>
+
+#if !defined(__GLIBC__)
+#include <string.h>
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(string, posix_strerror_r) {
+ char buf[256];
+
+ // Valid.
+ ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf)));
+ ASSERT_STREQ("Success", buf);
+ ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf)));
+ ASSERT_STREQ("Operation not permitted", buf);
+
+ // Invalid.
+ ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf)));
+ ASSERT_STREQ("Unknown error -1", buf);
+ ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf)));
+ ASSERT_STREQ("Unknown error 1234", buf);
+
+ // Buffer too small.
+ errno = 0;
+ memset(buf, 0, sizeof(buf));
+ ASSERT_EQ(-1, strerror_r(4567, buf, 2));
+ ASSERT_STREQ("U", buf);
+ // The POSIX strerror_r sets errno to ERANGE (the GNU one doesn't).
+ ASSERT_EQ(ERANGE, errno);
+}
+#else
+# if __GLIBC_PREREQ(2, 15)
+# error this test should work now
+# endif
+#endif
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index a3c6abb..7db8e21 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define _GNU_SOURCE 1
+
#include <string.h>
#include <errno.h>
@@ -72,28 +74,34 @@ TEST(string, strerror_concurrent) {
#endif // __BIONIC__
}
-TEST(string, strerror_r) {
-#if defined(__BIONIC__) // glibc's strerror_r doesn't even have the same signature as the POSIX one.
+TEST(string, gnu_strerror_r) {
char buf[256];
+ // Note that glibc doesn't necessarily write into the buffer.
+
// Valid.
- ASSERT_EQ(0, strerror_r(0, buf, sizeof(buf)));
+ ASSERT_STREQ("Success", strerror_r(0, buf, sizeof(buf)));
+#if defined(__BIONIC__)
ASSERT_STREQ("Success", buf);
- ASSERT_EQ(0, strerror_r(1, buf, sizeof(buf)));
+#endif
+ ASSERT_STREQ("Operation not permitted", strerror_r(1, buf, sizeof(buf)));
+#if defined(__BIONIC__)
ASSERT_STREQ("Operation not permitted", buf);
+#endif
// Invalid.
- ASSERT_EQ(0, strerror_r(-1, buf, sizeof(buf)));
+ ASSERT_STREQ("Unknown error -1", strerror_r(-1, buf, sizeof(buf)));
ASSERT_STREQ("Unknown error -1", buf);
- ASSERT_EQ(0, strerror_r(1234, buf, sizeof(buf)));
+ ASSERT_STREQ("Unknown error 1234", strerror_r(1234, buf, sizeof(buf)));
ASSERT_STREQ("Unknown error 1234", buf);
// Buffer too small.
- ASSERT_EQ(-1, strerror_r(0, buf, 2));
- ASSERT_EQ(ERANGE, errno);
-#else // __BIONIC__
- GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif // __BIONIC__
+ errno = 0;
+ memset(buf, 0, sizeof(buf));
+ ASSERT_EQ(buf, strerror_r(4567, buf, 2));
+ ASSERT_STREQ("U", buf);
+ // The GNU strerror_r doesn't set errno (the POSIX one sets it to ERANGE).
+ ASSERT_EQ(0, errno);
}
TEST(string, strsignal) {