libc: cleanup strchr

Move strchr to a .cpp file, and change to bionic directory.

Change-Id: I64ade7df326c0a9a714aca4caf5647b6833b1c97
diff --git a/libc/Android.mk b/libc/Android.mk
index eaeb6fc..21cd33e 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -66,7 +66,6 @@
 	string/index.c \
 	string/strcasecmp.c \
 	string/strcat.c \
-	string/strchr.c \
 	string/strcspn.c \
 	string/strdup.c \
 	string/strlcat.c \
@@ -238,6 +237,7 @@
     bionic/signalfd.cpp \
     bionic/sigwait.cpp \
     bionic/__strcat_chk.cpp \
+    bionic/strchr.cpp \
     bionic/__strcpy_chk.cpp \
     bionic/strerror.cpp \
     bionic/strerror_r.cpp \
diff --git a/libc/string/strchr.c b/libc/bionic/strchr.cpp
similarity index 77%
rename from libc/string/strchr.c
rename to libc/bionic/strchr.cpp
index 29acca5..972029e 100644
--- a/libc/string/strchr.c
+++ b/libc/bionic/strchr.cpp
@@ -1,4 +1,3 @@
-/*	$OpenBSD: index.c,v 1.5 2005/08/08 08:05:37 espie Exp $ */
 /*-
  * Copyright (c) 1990 The Regents of the University of California.
  * All rights reserved.
@@ -31,21 +30,21 @@
 #include <string.h>
 #include "libc_logging.h"
 
-char *
-__strchr_chk(const char *p, int ch, size_t s_len)
-{
-	for (;; ++p, s_len--) {
-		if (s_len == 0)
-			__fortify_chk_fail("strchr read beyond buffer", 0);
-		if (*p == (char) ch)
-			return((char *)p);
-		if (!*p)
-			return((char *)NULL);
-	}
-	/* NOTREACHED */
+extern "C" char* __strchr_chk(const char* p, int ch, size_t s_len) {
+  for (;; ++p, s_len--) {
+    if (__predict_false(s_len == 0)) {
+      __fortify_chk_fail("read beyond buffer", 0);
+    }
+    if (*p == static_cast<char>(ch)) {
+      return const_cast<char*>(p);
+    }
+    if (*p == '\0') {
+      return NULL;
+    }
+  }
+  /* NOTREACHED */
 }
 
-char *
-strchr(const char *p, int ch) {
-    return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
+extern "C" char* strchr(const char* p, int ch) {
+  return __strchr_chk(p, ch, __BIONIC_FORTIFY_UNKNOWN_SIZE);
 }
diff --git a/tests/fortify2_test.cpp b/tests/fortify2_test.cpp
index 09c094c..ea890fe 100644
--- a/tests/fortify2_test.cpp
+++ b/tests/fortify2_test.cpp
@@ -45,6 +45,15 @@
 }
 
 #if __BIONIC__
+TEST(Fortify2_DeathTest, strchr_fortified2) {
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  foo myfoo;
+  memcpy(myfoo.a, "0123456789", sizeof(myfoo.a));
+  myfoo.b[0] = '\0';
+  ASSERT_EXIT(printf("%s", strchr(myfoo.a, 'a')),
+              testing::KilledBySignal(SIGSEGV), "");
+}
+
 TEST(Fortify2_DeathTest, strrchr_fortified2) {
   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
   foo myfoo;
diff --git a/tests/string_test.cpp b/tests/string_test.cpp
index eb10c16..63bfadb 100644
--- a/tests/string_test.cpp
+++ b/tests/string_test.cpp
@@ -209,6 +209,13 @@
   }
 }
 
+TEST(string, strchr_with_0) {
+  char buf[10];
+  const char* s = "01234";
+  memcpy(buf, s, strlen(s) + 1);
+  EXPECT_TRUE(strchr(buf, '\0') == (buf + strlen(s)));
+}
+
 TEST(string, strchr) {
   int seek_char = random() & 255;