<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <Cocoa/Cocoa.h>
#include <dirent.h>

extern "C" {
#include <sandbox.h>
}

#include "base/file_util.h"
#include "base/file_path.h"
#include "base/test/multiprocess_test.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/common/sandbox_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

namespace {

static const char* kSandboxAccessPathKey = "sandbox_dir";
static const char* kDeniedSuffix = "_denied";

}  // namespace

// Tests need to be in the same namespace as the sandbox::Sandbox class to be
// useable with FRIEND_TEST() declaration.
namespace sandbox {

class MacDirAccessSandboxTest : public base::MultiProcessTest {
 public:
  bool CheckSandbox(const std::string& directory_to_try) {
    setenv(kSandboxAccessPathKey, directory_to_try.c_str(), 1);
    base::ProcessHandle child_process = SpawnChild("mac_sandbox_path_access",
                                                   false);
    if (child_process == base::kNullProcessHandle) {
      LOG(WARNING) << "SpawnChild failed";
      return false;
    }
    int code = -1;
    if (!base::WaitForExitCode(child_process, &code)) {
      LOG(WARNING) << "base::WaitForExitCode failed";
      return false;
    }
    return code == 0;
  }
};

TEST_F(MacDirAccessSandboxTest, StringEscape) {
  const struct string_escape_test_data {
  const char* to_escape;
  const char* escaped;
  } string_escape_cases[] = {
    {"", ""},
    {"\b\f\n\r\t\\\"", "\\b\\f\\n\\r\\t\\\\\\\""},
    {"/'", "/'"},
    {"sandwich", "sandwich"},
    {"(sandwich)", "(sandwich)"},
    {"^\u2135.\u2136$", "^\\u2135.\\u2136$"},
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(string_escape_cases); ++i) {
    std::string out;
    std::string in(string_escape_cases[i].to_escape);
    EXPECT_TRUE(Sandbox::QuotePlainString(in, &out));
    EXPECT_EQ(string_escape_cases[i].escaped, out);
  }
}

TEST_F(MacDirAccessSandboxTest, RegexEscape) {
  const std::string kSandboxEscapeSuffix("(/|$)");
  const struct regex_test_data {
    const wchar_t *to_escape;
    const char* escaped;
  } regex_cases[] = {
    {L"", ""},
    {L"/'", "/'"},  // / & ' characters don't need escaping.
    {L"sandwich", "sandwich"},
    {L"(sandwich)", "\\(sandwich\\)"},
  };

  // Check that all characters whose values are smaller than 32 [1F] are
  // rejected by the regex escaping code.
  {
    std::string out;
    char fail_string[] = {31, 0};
    char ok_string[] = {32, 0};
    EXPECT_FALSE(Sandbox::QuoteStringForRegex(fail_string, &out));
    EXPECT_TRUE(Sandbox::QuoteStringForRegex(ok_string, &out));
  }

  // Check that all characters whose values are larger than 126 [7E] are
  // rejected by the regex escaping code.
  {
    std::string out;
    EXPECT_TRUE(Sandbox::QuoteStringForRegex("}", &out));   // } == 0x7D == 125
    EXPECT_FALSE(Sandbox::QuoteStringForRegex("~", &out));  // ~ == 0x7E == 126
    EXPECT_FALSE(
        Sandbox::QuoteStringForRegex(WideToUTF8(L"^\u2135.\u2136$"), &out));
  }

  {
    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(regex_cases); ++i) {
      std::string out;
      std::string in = WideToUTF8(regex_cases[i].to_escape);
      EXPECT_TRUE(Sandbox::QuoteStringForRegex(in, &out));
      std::string expected("^");
      expected.append(regex_cases[i].escaped);
      expected.append(kSandboxEscapeSuffix);
      EXPECT_EQ(expected, out);
    }
  }

  {
    std::string in_utf8("\\^.$|()[]*+?{}");
    std::string expected;
    expected.push_back('^');
    for (size_t i = 0; i < in_utf8.length(); ++i) {
      expected.push_back('\\');
      expected.push_back(in_utf8[i]);
    }
    expected.append(kSandboxEscapeSuffix);

    std::string out;
    EXPECT_TRUE(Sandbox::QuoteStringForRegex(in_utf8, &out));
    EXPECT_EQ(expected, out);

  }
}

// A class to handle auto-deleting a directory.
class ScopedDirectoryDelete {
 public:
  inline void operator()(FilePath* x) const {
    if (x) {
      file_util::Delete(*x, true);
    }
  }
};

typedef scoped_ptr_malloc<FilePath, ScopedDirectoryDelete> ScopedDirectory;

TEST_F(MacDirAccessSandboxTest, SandboxAccess) {
  using file_util::CreateDirectory;

  FilePath tmp_dir;
  ASSERT_TRUE(file_util::CreateNewTempDirectory("", &tmp_dir));
  // This step is important on OS X since the sandbox only understands "real"
  // paths and the paths CreateNewTempDirectory() returns are empirically in
  // /var which is a symlink to /private/var .
  Sandbox::GetCanonicalSandboxPath(&tmp_dir);
  ScopedDirectory cleanup(&tmp_dir);
<commit_msg>Disables MacDirAccessSandboxTest.SandboxAccess as it keeps timing out.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#import <Cocoa/Cocoa.h>
#include <dirent.h>

extern "C" {
#include <sandbox.h>
}

#include "base/file_util.h"
#include "base/file_path.h"
#include "base/test/multiprocess_test.h"
#include "base/sys_string_conversions.h"
#include "base/utf_string_conversions.h"
#include "content/common/sandbox_mac.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

namespace {

static const char* kSandboxAccessPathKey = "sandbox_dir";
static const char* kDeniedSuffix = "_denied";

}  // namespace

// Tests need to be in the same namespace as the sandbox::Sandbox class to be
// useable with FRIEND_TEST() declaration.
namespace sandbox {

class MacDirAccessSandboxTest : public base::MultiProcessTest {
 public:
  bool CheckSandbox(const std::string& directory_to_try) {
    setenv(kSandboxAccessPathKey, directory_to_try.c_str(), 1);
    base::ProcessHandle child_process = SpawnChild("mac_sandbox_path_access",
                                                   false);
    if (child_process == base::kNullProcessHandle) {
      LOG(WARNING) << "SpawnChild failed";
      return false;
    }
    int code = -1;
    if (!base::WaitForExitCode(child_process, &code)) {
      LOG(WARNING) << "base::WaitForExitCode failed";
      return false;
    }
    return code == 0;
  }
};

TEST_F(MacDirAccessSandboxTest, StringEscape) {
  const struct string_escape_test_data {
  const char* to_escape;
  const char* escaped;
  } string_escape_cases[] = {
    {"", ""},
    {"\b\f\n\r\t\\\"", "\\b\\f\\n\\r\\t\\\\\\\""},
    {"/'", "/'"},
    {"sandwich", "sandwich"},
    {"(sandwich)", "(sandwich)"},
    {"^\u2135.\u2136$", "^\\u2135.\\u2136$"},
  };

  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(string_escape_cases); ++i) {
    std::string out;
    std::string in(string_escape_cases[i].to_escape);
    EXPECT_TRUE(Sandbox::QuotePlainString(in, &out));
    EXPECT_EQ(string_escape_cases[i].escaped, out);
  }
}

TEST_F(MacDirAccessSandboxTest, RegexEscape) {
  const std::string kSandboxEscapeSuffix("(/|$)");
  const struct regex_test_data {
    const wchar_t *to_escape;
    const char* escaped;
  } regex_cases[] = {
    {L"", ""},
    {L"/'", "/'"},  // / & ' characters don't need escaping.
    {L"sandwich", "sandwich"},
    {L"(sandwich)", "\\(sandwich\\)"},
  };

  // Check that all characters whose values are smaller than 32 [1F] are
  // rejected by the regex escaping code.
  {
    std::string out;
    char fail_string[] = {31, 0};
    char ok_string[] = {32, 0};
    EXPECT_FALSE(Sandbox::QuoteStringForRegex(fail_string, &out));
    EXPECT_TRUE(Sandbox::QuoteStringForRegex(ok_string, &out));
  }

  // Check that all characters whose values are larger than 126 [7E] are
  // rejected by the regex escaping code.
  {
    std::string out;
    EXPECT_TRUE(Sandbox::QuoteStringForRegex("}", &out));   // } == 0x7D == 125
    EXPECT_FALSE(Sandbox::QuoteStringForRegex("~", &out));  // ~ == 0x7E == 126
    EXPECT_FALSE(
        Sandbox::QuoteStringForRegex(WideToUTF8(L"^\u2135.\u2136$"), &out));
  }

  {
    for (size_t i = 0; i < ARRAYSIZE_UNSAFE(regex_cases); ++i) {
      std::string out;
      std::string in = WideToUTF8(regex_cases[i].to_escape);
      EXPECT_TRUE(Sandbox::QuoteStringForRegex(in, &out));
      std::string expected("^");
      expected.append(regex_cases[i].escaped);
      expected.append(kSandboxEscapeSuffix);
      EXPECT_EQ(expected, out);
    }
  }

  {
    std::string in_utf8("\\^.$|()[]*+?{}");
    std::string expected;
    expected.push_back('^');
    for (size_t i = 0; i < in_utf8.length(); ++i) {
      expected.push_back('\\');
      expected.push_back(in_utf8[i]);
    }
    expected.append(kSandboxEscapeSuffix);

    std::string out;
    EXPECT_TRUE(Sandbox::QuoteStringForRegex(in_utf8, &out));
    EXPECT_EQ(expected, out);

  }
}

// A class to handle auto-deleting a directory.
class ScopedDirectoryDelete {
 public:
  inline void operator()(FilePath* x) const {
    if (x) {
      file_util::Delete(*x, true);
    }
  }
};

typedef scoped_ptr_malloc<FilePath, ScopedDirectoryDelete> ScopedDirectory;

// Disabled as times out, taking out remaining tests: 89170.
TEST_F(MacDirAccessSandboxTest, DISABLED_SandboxAccess) {
  using file_util::CreateDirectory;

  FilePath tmp_dir;
  ASSERT_TRUE(file_util::CreateNewTempDirectory("", &tmp_dir));
  // This step is important on OS X since the sandbox only understands "real"
  // paths and the paths CreateNewTempDirectory() returns are empirically in
  // /var which is a symlink to /private/var .
  Sandbox::GetCanonicalSandboxPath(&tmp_dir);
  ScopedDirectory cleanup(&tmp_dir);

{'fraction_non_alphanumeric': 0.15279658368919904, 'fraction_numerical': 0.013644412040412456, 'mean_word_length': 3.702252693437806, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3624332', 'n_tokens_mistral': 3492, 'n_tokens_neox': 3302, 'n_words': 715}