1341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//===-- sanitizer_libc_test.cc --------------------------------------------===//
2341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//
3341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//                     The LLVM Compiler Infrastructure
4341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//
5341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// This file is distributed under the University of Illinois Open Source
6341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// License. See LICENSE.TXT for details.
7341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//
8341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//===----------------------------------------------------------------------===//
9341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// Tests for sanitizer_libc.h.
10341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko//===----------------------------------------------------------------------===//
113d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include <algorithm>
12341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko
134c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#include "sanitizer_common/sanitizer_common.h"
14341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko#include "sanitizer_common/sanitizer_libc.h"
15a615b26e3e3c2da0b2f950f506f6c2c220430c19Sergey Matveev#include "sanitizer_common/sanitizer_platform.h"
16341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko#include "gtest/gtest.h"
17341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko
183d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if SANITIZER_WINDOWS
193d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#define NOMINMAX
203d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#include <windows.h>
213d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#undef NOMINMAX
223d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
233d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if SANITIZER_POSIX
244c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov# include <sys/stat.h>
25259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar# include "sanitizer_common/sanitizer_posix.h"
264c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#endif
274c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
28341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko// A regression test for internal_memmove() implementation.
29341588afadc46bf6f0dc7babd6d531209aba5202Alexander PotapenkoTEST(SanitizerCommon, InternalMemmoveRegression) {
30341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  char src[] = "Hello World";
31341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  char *dest = src + 6;
32341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  __sanitizer::internal_memmove(dest, src, 5);
33341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  EXPECT_EQ(dest[0], src[0]);
34341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko  EXPECT_EQ(dest[4], src[4]);
35341588afadc46bf6f0dc7babd6d531209aba5202Alexander Potapenko}
36eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany
37eb2809311c94b73c269ccef8d68ae368642e5754Kostya SerebryanyTEST(SanitizerCommon, mem_is_zero) {
38eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  size_t size = 128;
39eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  char *x = new char[size];
40eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  memset(x, 0, size);
41eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  for (size_t pos = 0; pos < size; pos++) {
42eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    x[pos] = 1;
43eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    for (size_t beg = 0; beg < size; beg++) {
44eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany      for (size_t end = beg; end < size; end++) {
45eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany        // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
46eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany        if (beg <= pos && pos < end)
47eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany          EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
48eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany        else
49eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany          EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
50eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany      }
51eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    }
52eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany    x[pos] = 0;
53eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  }
54eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany  delete [] x;
55eb2809311c94b73c269ccef8d68ae368642e5754Kostya Serebryany}
564c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
572be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanovstruct stat_and_more {
582be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  struct stat st;
592be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  unsigned char z;
602be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov};
612be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov
6286277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic void temp_file_name(char *buf, size_t bufsize, const char *prefix) {
633d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if SANITIZER_WINDOWS
643d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  buf[0] = '\0';
653d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  char tmp_dir[MAX_PATH];
663d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  if (!::GetTempPathA(MAX_PATH, tmp_dir))
673d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    return;
683d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  // GetTempFileNameA needs a MAX_PATH buffer.
693d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  char tmp_path[MAX_PATH];
703d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  if (!::GetTempFileNameA(tmp_dir, prefix, 0, tmp_path))
713d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    return;
723d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  internal_strncpy(buf, tmp_path, bufsize);
733d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#else
7486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  const char *tmpdir = "/tmp";
7586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#if SANITIZER_ANDROID
7686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // I don't know a way to query temp directory location on Android without
7786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // going through Java interfaces. The code below is not ideal, but should
7886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // work. May require "adb root", but it is needed for almost any use of ASan
7986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  // on Android already.
8086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  tmpdir = GetEnv("EXTERNAL_STORAGE");
8186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
8286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  u32 uid = GetUid();
8386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  internal_snprintf(buf, bufsize, "%s/%s%d", tmpdir, prefix, uid);
843d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#endif
8586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
8686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
874c9317a7b61e136f832d2ede70f557963fd46bceAlexey SamsonovTEST(SanitizerCommon, FileOps) {
884c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  const char *str1 = "qwerty";
894c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  uptr len1 = internal_strlen(str1);
904c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  const char *str2 = "zxcv";
914c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  uptr len2 = internal_strlen(str2);
924c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
9386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  char tmpfile[128];
9486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp.");
95259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  fd_t fd = OpenFile(tmpfile, WrOnly);
96259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  ASSERT_NE(fd, kInvalidFd);
973d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  uptr bytes_written = 0;
983d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_TRUE(WriteToFile(fd, str1, len1, &bytes_written));
993d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(len1, bytes_written);
1003d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_TRUE(WriteToFile(fd, str2, len2, &bytes_written));
1013d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(len2, bytes_written);
102259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CloseFile(fd);
1034c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
1043d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_TRUE(FileExists(tmpfile));
1053d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
106259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  fd = OpenFile(tmpfile, RdOnly);
107259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  ASSERT_NE(fd, kInvalidFd);
1083d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1093d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if SANITIZER_POSIX
1103d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  // The stat wrappers are posix-only.
1114c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  uptr fsize = internal_filesize(fd);
1124c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(len1 + len2, fsize);
1134c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
1144c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  struct stat st1, st2, st3;
11586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_EQ(0u, internal_stat(tmpfile, &st1));
11686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  EXPECT_EQ(0u, internal_lstat(tmpfile, &st2));
1179578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  EXPECT_EQ(0u, internal_fstat(fd, &st3));
1184c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(fsize, (uptr)st3.st_size);
1192be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov
1202be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  // Verify that internal_fstat does not write beyond the end of the supplied
1212be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  // buffer.
1222be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  struct stat_and_more sam;
1232be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  memset(&sam, 0xAB, sizeof(sam));
1249578a3ecfc35a264ede1135033398e2a77a6cad6Peter Collingbourne  EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
1252be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  EXPECT_EQ(0xAB, sam.z);
1262be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  EXPECT_NE(0xAB, sam.st.st_size);
1272be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov  EXPECT_NE(0, sam.st.st_size);
1284c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov#endif
1294c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov
1304c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  char buf[64] = {};
1313d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  uptr bytes_read = 0;
1323d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_TRUE(ReadFromFile(fd, buf, len1, &bytes_read));
1333d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(len1, bytes_read);
1344c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
1354c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ((char)0, buf[len1 + 1]);
1364c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  internal_memset(buf, 0, len1);
1373d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_TRUE(ReadFromFile(fd, buf, len2, &bytes_read));
1383d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(len2, bytes_read);
1394c9317a7b61e136f832d2ede70f557963fd46bceAlexey Samsonov  EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
140259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CloseFile(fd);
1413d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1423d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if SANITIZER_WINDOWS
1433d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  // No sanitizer needs to delete a file on Windows yet. If we ever do, we can
1443d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  // add a portable wrapper and test it from here.
1453d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  ::DeleteFileA(&tmpfile[0]);
1463d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#else
14786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  internal_unlink(tmpfile);
1482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#endif
1493d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar}
1503d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1513d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarstatic const size_t kStrlcpyBufSize = 8;
1523d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainarvoid test_internal_strlcpy(char *dbuf, const char *sbuf) {
1533d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  uptr retval = 0;
1543d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  retval = internal_strlcpy(dbuf, sbuf, kStrlcpyBufSize);
1553d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strncmp(dbuf, sbuf, kStrlcpyBufSize - 1), 0);
1563d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strlen(dbuf),
1573d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar            std::min(internal_strlen(sbuf), (uptr)(kStrlcpyBufSize - 1)));
1583d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(retval, internal_strlen(sbuf));
1593d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1603d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  // Test with shorter maxlen.
1613d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  uptr maxlen = 2;
1623d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  if (internal_strlen(sbuf) > maxlen) {
1633d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    retval = internal_strlcpy(dbuf, sbuf, maxlen);
1643d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    EXPECT_EQ(internal_strncmp(dbuf, sbuf, maxlen - 1), 0);
1653d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar    EXPECT_EQ(internal_strlen(dbuf), maxlen - 1);
1663d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  }
1673d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar}
1682be3a283939d4fc14ad86f6cd8be34b1468f22baEvgeniy Stepanov
16972870db5f2e0e83b2e925eef594dacfae275a8deAlexey SamsonovTEST(SanitizerCommon, InternalStrFunctions) {
17072870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  const char *haystack = "haystack";
17172870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
17272870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
17372870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(0, internal_strchr(haystack, 'z'));
17472870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov  EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));
1753d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1763d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  char dbuf[kStrlcpyBufSize] = {};
1773d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  const char *samesizestr = "1234567";
1783d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  const char *shortstr = "123";
1793d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  const char *longerstr = "123456789";
1803d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1813d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  // Test internal_strlcpy.
1823d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  internal_strlcpy(dbuf, shortstr, 0);
1833d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(dbuf[0], 0);
1843d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(dbuf[0], 0);
1853d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  test_internal_strlcpy(dbuf, samesizestr);
1863d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  test_internal_strlcpy(dbuf, shortstr);
1873d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  test_internal_strlcpy(dbuf, longerstr);
1883d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1893d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  // Test internal_strlcat.
1903d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  char dcatbuf[kStrlcpyBufSize] = {};
1913d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  uptr retval = 0;
1923d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  retval = internal_strlcat(dcatbuf, "aaa", 0);
1933d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)0);
1943d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(retval, (uptr)3);
1953d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
1963d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
1973d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strcmp(dcatbuf, "123"), 0);
1983d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)3);
1993d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(retval, (uptr)3);
2003d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
2013d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
2023d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strcmp(dcatbuf, "123123"), 0);
2033d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)6);
2043d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(retval, (uptr)6);
2053d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar
2063d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
2073d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strcmp(dcatbuf, "1231231"), 0);
2083d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(internal_strlen(dcatbuf), (uptr)7);
2093d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar  EXPECT_EQ(retval, (uptr)9);
21072870db5f2e0e83b2e925eef594dacfae275a8deAlexey Samsonov}
21186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
21286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// FIXME: File manipulations are not yet supported on Windows
2133d763c0d3700e73b3aead8e65e04ec28efc56138Pirama Arumuga Nainar#if SANITIZER_POSIX && !SANITIZER_MAC
21486277eb844c4983c81de62d7c050e92fe7155788Stephen HinesTEST(SanitizerCommon, InternalMmapWithOffset) {
21586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  char tmpfile[128];
21686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  temp_file_name(tmpfile, sizeof(tmpfile),
21786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines                 "sanitizer_common.internalmmapwithoffset.tmp.");
218259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  fd_t fd = OpenFile(tmpfile, RdWr);
219259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  ASSERT_NE(fd, kInvalidFd);
22086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
22186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  uptr page_size = GetPageSizeCached();
222259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  uptr res = internal_ftruncate(fd, page_size * 2);
22386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ASSERT_FALSE(internal_iserror(res));
22486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
22586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  res = internal_lseek(fd, page_size, SEEK_SET);
22686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ASSERT_FALSE(internal_iserror(res));
22786277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
22886277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  res = internal_write(fd, "AB", 2);
22986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ASSERT_FALSE(internal_iserror(res));
23086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
23186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size);
23286277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ASSERT_NE(nullptr, p);
23386277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
23486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ASSERT_EQ('A', p[0]);
23586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  ASSERT_EQ('B', p[1]);
23686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines
237259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  CloseFile(fd);
238259f7063e3e4c4b94dded1e90ab0a943d0fa737bPirama Arumuga Nainar  UnmapOrDie(p, page_size);
23986277eb844c4983c81de62d7c050e92fe7155788Stephen Hines  internal_unlink(tmpfile);
24086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines}
24186277eb844c4983c81de62d7c050e92fe7155788Stephen Hines#endif
242