Add tests for __strcpy_chk()

Change-Id: I5675d04fcd471732c1b87b83879a54fbcd27762e
diff --git a/tests/fortify1_test.cpp b/tests/fortify1_test.cpp
index a9d8afd..b5cf208 100644
--- a/tests/fortify1_test.cpp
+++ b/tests/fortify1_test.cpp
@@ -23,6 +23,8 @@
 #if __BIONIC__
 // We have to say "DeathTest" here so gtest knows to run this test (which exits)
 // in its own process.
+
+// multibyte target where we over fill (should fail)
 TEST(Fortify1_DeathTest, strcpy_fortified) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   char buf[10];
@@ -31,6 +33,33 @@
   free(orig);
 }
 
+// zero sized target with "\0" source (should fail)
+TEST(Fortify1_DeathTest, strcpy2_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[0];
+  char *orig = strdup("");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
+// zero sized target with longer source (should fail)
+TEST(Fortify1_DeathTest, strcpy3_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[0];
+  char *orig = strdup("1");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
+// one byte target with longer source (should fail)
+TEST(Fortify1_DeathTest, strcpy4_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[1];
+  char *orig = strdup("12");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
 TEST(Fortify1_DeathTest, strlen_fortified) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   char buf[10];
diff --git a/tests/fortify2_test.cpp b/tests/fortify2_test.cpp
index eee5770..f0c2e77 100644
--- a/tests/fortify2_test.cpp
+++ b/tests/fortify2_test.cpp
@@ -21,6 +21,8 @@
 #include <string.h>
 
 struct foo {
+  char empty[0];
+  char one[1];
   char a[10];
   char b[10];
 };
@@ -45,6 +47,36 @@
 }
 
 #if __BIONIC__
+// zero sized target with "\0" source (should fail)
+TEST(Fortify2_DeathTest, strcpy_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  char* src = strdup("");
+  ASSERT_EXIT(strcpy(myfoo.empty, src),
+              testing::KilledBySignal(SIGSEGV), "");
+  free(src);
+}
+
+// zero sized target with longer source (should fail)
+TEST(Fortify2_DeathTest, strcpy2_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  char* src = strdup("1");
+  ASSERT_EXIT(strcpy(myfoo.empty, src),
+              testing::KilledBySignal(SIGSEGV), "");
+  free(src);
+}
+
+// one byte target with longer source (should fail)
+TEST(Fortify2_DeathTest, strcpy3_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  char* src = strdup("12");
+  ASSERT_EXIT(strcpy(myfoo.one, src),
+              testing::KilledBySignal(SIGSEGV), "");
+  free(src);
+}
+
 TEST(Fortify2_DeathTest, strchr_fortified2) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   foo myfoo;
@@ -111,6 +143,7 @@
 /***********************************************************/
 
 #if __BIONIC__
+// multibyte target where we over fill (should fail)
 TEST(Fortify2_DeathTest, strcpy_fortified) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   char buf[10];
@@ -119,6 +152,33 @@
   free(orig);
 }
 
+// zero sized target with "\0" source (should fail)
+TEST(Fortify2_DeathTest, strcpy2_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[0];
+  char *orig = strdup("");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
+// zero sized target with longer source (should fail)
+TEST(Fortify2_DeathTest, strcpy3_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[0];
+  char *orig = strdup("1");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
+// one byte target with longer source (should fail)
+TEST(Fortify2_DeathTest, strcpy4_fortified) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  char buf[1];
+  char *orig = strdup("12");
+  ASSERT_EXIT(strcpy(buf, orig), testing::KilledBySignal(SIGSEGV), "");
+  free(orig);
+}
+
 TEST(Fortify2_DeathTest, strlen_fortified) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   char buf[10];
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index a0924dc..91d1904 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -209,6 +209,53 @@
   }
 }
 
+// one byte target with "\0" source
+TEST(string, strcpy2) {
+  char buf[1];
+  char* orig = strdup("");
+  strcpy(buf, orig);
+  ASSERT_EQ('\0', buf[0]);
+  free(orig);
+}
+
+// multibyte target where we under fill target
+TEST(string, strcpy3) {
+  char buf[10];
+  char* orig = strdup("12345");
+  memset(buf, 'A', sizeof(buf));
+  strcpy(buf, orig);
+  ASSERT_EQ('1',  buf[0]);
+  ASSERT_EQ('2',  buf[1]);
+  ASSERT_EQ('3',  buf[2]);
+  ASSERT_EQ('4',  buf[3]);
+  ASSERT_EQ('5',  buf[4]);
+  ASSERT_EQ('\0', buf[5]);
+  ASSERT_EQ('A',  buf[6]);
+  ASSERT_EQ('A',  buf[7]);
+  ASSERT_EQ('A',  buf[8]);
+  ASSERT_EQ('A',  buf[9]);
+  free(orig);
+}
+
+// multibyte target where we fill target exactly
+TEST(string, strcpy4) {
+  char buf[10];
+  char* orig = strdup("123456789");
+  memset(buf, 'A', sizeof(buf));
+  strcpy(buf, orig);
+  ASSERT_EQ('1',  buf[0]);
+  ASSERT_EQ('2',  buf[1]);
+  ASSERT_EQ('3',  buf[2]);
+  ASSERT_EQ('4',  buf[3]);
+  ASSERT_EQ('5',  buf[4]);
+  ASSERT_EQ('6',  buf[5]);
+  ASSERT_EQ('7',  buf[6]);
+  ASSERT_EQ('8',  buf[7]);
+  ASSERT_EQ('9',  buf[8]);
+  ASSERT_EQ('\0', buf[9]);
+  free(orig);
+}
+
 TEST(string, strcat2) {
   char buf[10];
   memset(buf, 'A', sizeof(buf));