// Copyright 2021 The BoringSSL Authors
//
// 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
//
//     https://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.

#include <algorithm>
#include <string>
#include <vector>
#include <map>

#include <openssl/bio.h>
#include <openssl/conf.h>

#include <gtest/gtest.h>

#include "internal.h"


BSSL_NAMESPACE_BEGIN
namespace {

// A |CONF| is an unordered list of sections, where each section contains an
// ordered list of (name, value) pairs.
using ConfModel =
    std::map<std::string, std::vector<std::pair<std::string, std::string>>>;

static void ExpectConfEquals(const CONF *conf, const ConfModel &model) {
  // There is always a default section, even if empty. This is an easy mistake
  // to make in test data, so test for it.
  EXPECT_NE(model.find("default"), model.end())
      << "Model does not have a default section";

  size_t total_values = 0;
  for (const auto &pair : model) {
    const std::string &section = pair.first;
    SCOPED_TRACE(section);

    const STACK_OF(CONF_VALUE) *values =
        NCONF_get_section(conf, section.c_str());
    ASSERT_TRUE(values);
    total_values += pair.second.size();

    EXPECT_EQ(sk_CONF_VALUE_num(values), pair.second.size());

    // If the lengths do not match, still compare up to the smaller of the two,
    // to aid debugging.
    size_t min_len = std::min(sk_CONF_VALUE_num(values), pair.second.size());
    for (size_t i = 0; i < min_len; i++) {
      SCOPED_TRACE(i);
      const std::string &name = pair.second[i].first;
      const std::string &value = pair.second[i].second;

      const CONF_VALUE *v = sk_CONF_VALUE_value(values, i);
      EXPECT_EQ(v->section, section);
      EXPECT_EQ(v->name, name);
      EXPECT_EQ(v->value, value);

      const char *str = NCONF_get_string(conf, section.c_str(), name.c_str());
      ASSERT_NE(str, nullptr);
      EXPECT_EQ(str, value);

      if (section == "default") {
        // nullptr is interpreted as the default section.
        str = NCONF_get_string(conf, nullptr, name.c_str());
        ASSERT_NE(str, nullptr);
        EXPECT_EQ(str, value);
      }
    }
  }

  // Unrecognized sections must return nullptr.
  EXPECT_EQ(NCONF_get_section(conf, "must_not_appear_in_tests"), nullptr);
  EXPECT_EQ(NCONF_get_string(conf, "must_not_appear_in_tests",
                             "must_not_appear_in_tests"),
            nullptr);
  if (!model.empty()) {
    // Valid section, invalid name.
    EXPECT_EQ(NCONF_get_string(conf, model.begin()->first.c_str(),
                               "must_not_appear_in_tests"),
              nullptr);
    if (!model.begin()->second.empty()) {
      // Invalid section, valid name.
      EXPECT_EQ(NCONF_get_string(conf, "must_not_appear_in_tests",
                                 model.begin()->second.front().first.c_str()),
                nullptr);
    }
  }

  // There should not be any other values in |conf|. |conf| currently stores
  // both sections and values in the same map.
  EXPECT_EQ(lh_CONF_SECTION_num_items(conf->sections), model.size());
  EXPECT_EQ(lh_CONF_VALUE_num_items(conf->values), total_values);
}

TEST(ConfTest, Parse) {
  const struct {
    std::string in;
    ConfModel model;
  } kTests[] = {
      // Test basic parsing.
      {
          R"(# Comment

key=value

[section_name]
key=value2
)",
          {
              {"default", {{"key", "value"}}},
              {"section_name", {{"key", "value2"}}},
          },
      },

      // If a section is listed multiple times, keys add to the existing one.
      {
          R"(key1 = value1

[section1]
key2 = value2

[section2]
key3 = value3

[default]
key4 = value4

[section1]
key5 = value5
)",
          {
              {"default", {{"key1", "value1"}, {"key4", "value4"}}},
              {"section1", {{"key2", "value2"}, {"key5", "value5"}}},
              {"section2", {{"key3", "value3"}}},
          },
      },

      // Although the CONF parser internally uses a buffer size of 512 bytes to
      // read one line, it detects truncation and is able to parse long lines.
      {
          std::string(1000, 'a') + " = " + std::string(1000, 'b') + "\n",
          {
              {"default", {{std::string(1000, 'a'), std::string(1000, 'b')}}},
          },
      },

      // Trailing backslashes are line continations.
      {
          "key=\\\nvalue\nkey2=foo\\\nbar=baz",
          {
              {"default", {{"key", "value"}, {"key2", "foobar=baz"}}},
          },
      },

      // To be a line continuation, it must be at the end of the line.
      {
          "key=\\\nvalue\nkey2=foo\\ \nbar=baz",
          {
              {"default", {{"key", "value"}, {"key2", "foo"}, {"bar", "baz"}}},
          },
      },

      // A line continuation without any following line is ignored.
      {
          "key=value\\",
          {
              {"default", {{"key", "value"}}},
          },
      },

      // Values may have embedded whitespace, but leading and trailing
      // whitespace is dropped.
      {
          "key =  \t  foo   \t\t\tbar  \t  ",
          {
              {"default", {{"key", "foo   \t\t\tbar"}}},
          },
      },

      // Empty sections still end up in the file.
      {
          "[section1]\n[section2]\n[section3]\n",
          {
              {"default", {}},
              {"section1", {}},
              {"section2", {}},
              {"section3", {}},
          },
      },

      // Section names can contain spaces and punctuation.
      {
          "[This! Is. A? Section;]\nkey = value",
          {
              {"default", {}},
              {"This! Is. A? Section;", {{"key", "value"}}},
          },
      },

      // Trailing data after a section line is ignored.
      {
          "[section] key = value\nkey2 = value2\n",
          {
              {"default", {}},
              {"section", {{"key2", "value2"}}},
          },
      },

      // Comments may appear within a line. Escapes and quotes, however,
      // suppress the comment character.
      {
          R"(
key1 = # comment
key2 = "# not a comment"
key3 = '# not a comment'
key4 = `# not a comment`
key5 = \# not a comment
)",
          {
              {"default",
               {
                   {"key1", ""},
                   {"key2", "# not a comment"},
                   {"key3", "# not a comment"},
                   {"key4", "# not a comment"},
                   {"key5", "# not a comment"},
               }},
          },
      },

      // Quotes may appear in the middle of a string. Inside quotes, escape
      // sequences like \n are not evaluated. \X always evaluates to X.
      {
          R"(
key1 = mix "of" 'different' `quotes`
key2 = "`'"
key3 = "\r\n\b\t\""
key4 = '\r\n\b\t\''
key5 = `\r\n\b\t\``
)",
          {
              {"default",
               {
                   {"key1", "mix of different quotes"},
                   {"key2", "`'"},
                   {"key3", "rnbt\""},
                   {"key4", "rnbt'"},
                   {"key5", "rnbt`"},
               }},
          },
      },

      // Outside quotes, escape sequences like \n are evaluated. Unknown escapes
      // turn into the character.
      {
          R"(
key = \r\n\b\t\"\'\`\z
)",
          {
              {"default",
               {
                   {"key", "\r\n\b\t\"'`z"},
               }},
          },
      },

      // Escapes (but not quoting) work inside section names.
      {
          "[section\\ name]\nkey = value\n",
          {
              {"default", {}},
              {"section name", {{"key", "value"}}},
          },
      },

      // Escapes (but not quoting) are skipped over in key names, but they are
      // left unevaluated. This is probably a bug.
      {
          "key\\ name = value\n",
          {
              {"default", {{"key\\ name", "value"}}},
          },
      },

      // Keys can specify sections explicitly with ::.
      {
          R"(
[section1]
default::key1 = value1
section1::key2 = value2
section2::key3 = value3
section1::key4 = value4
section2::key5 = value5
default::key6 = value6
key7 = value7  # section1
)",
          {
              {"default", {{"key1", "value1"}, {"key6", "value6"}}},
              {"section1",
               {{"key2", "value2"}, {"key4", "value4"}, {"key7", "value7"}}},
              {"section2", {{"key3", "value3"}, {"key5", "value5"}}},
          },
      },

      // Punctuation is allowed in key names.
      {
          "key!%&*+,-./;?@^_|~1 = value\n",
          {
              {"default", {{"key!%&*+,-./;?@^_|~1", "value"}}},
          },
      },

      // Only the first equals counts as a key/value separator.
      {
          "key======",
          {
              {"default", {{"key", "====="}}},
          },
      },

      // Empty keys and empty values are allowed.
      {
          R"(
[both_empty]
=
[empty_key]
=value
[empty_value]
key=
[equals]
======
[]
empty=section
)",
          {
              {"default", {}},
              {"both_empty", {{"", ""}}},
              {"empty_key", {{"", "value"}}},
              {"empty_value", {{"key", ""}}},
              {"equals", {{"", "====="}}},
              {"", {{"empty", "section"}}},
          },
      },

      // After the first equals, the value can freely contain more equals.
      {
          "key1 = \\$value1\nkey2 = \"$value2\"",
          {
              {"default", {{"key1", "$value1"}, {"key2", "$value2"}}},
          },
      },

      // Non-ASCII bytes are allowed in values.
      {
          "key = \xe2\x98\x83",
          {
              {"default", {{"key", "\xe2\x98\x83"}}},
          },
      },

      // An escaped backslash is not a line continuation.
      {
          R"(
key1 = value1\\
key2 = value2
)",
          {
              {"default", {{"key1", "value1\\"}, {"key2", "value2"}}},
          },
      },

      // An unterminated escape sequence at the end of a line is silently
      // ignored. Normally, this would be a line continuation, but the line
      // continuation logic does not count backslashes and only looks at the
      // last two characters. This is probably a bug.
      {
          R"(
key1 = value1\\\
key2 = value2
)",
          {
              {"default", {{"key1", "value1\\"}, {"key2", "value2"}}},
          },
      },

      // The above also happens inside a quoted string, even allowing the quoted
      // string to be unterminated. This is also probably a bug.
      {
          R"(
key1 = "value1\\\
key2 = value2
)",
          {
              {"default", {{"key1", "value1\\"}, {"key2", "value2"}}},
          },
      },
  };
  for (const auto &t : kTests) {
    SCOPED_TRACE(t.in);
    UniquePtr<BIO> bio(BIO_new_mem_buf(t.in.data(), t.in.size()));
    ASSERT_TRUE(bio);
    UniquePtr<CONF> conf(NCONF_new(nullptr));
    ASSERT_TRUE(conf);
    ASSERT_TRUE(NCONF_load_bio(conf.get(), bio.get(), nullptr));

    ExpectConfEquals(conf.get(), t.model);
  }

  const char *kInvalidTests[] = {
      // Missing equals sign.
      "key",
      // Unterminated section heading.
      "[section",
      // Section names can only contain alphanumeric characters, punctuation,
      // and escapes. Quotes are not punctuation.
      "[\"section\"]",
      // Keys can only contain alphanumeric characters, punctuaion, and escapes.
      "key name = value",
      "\"key\" = value",
      // Variable references have been removed.
      "key1 = value1\nkey2 = $key1",
  };
  for (const auto &t : kInvalidTests) {
    SCOPED_TRACE(t);
    UniquePtr<BIO> bio(BIO_new_mem_buf(t, strlen(t)));
    ASSERT_TRUE(bio);
    UniquePtr<CONF> conf(NCONF_new(nullptr));
    ASSERT_TRUE(conf);
    EXPECT_FALSE(NCONF_load_bio(conf.get(), bio.get(), nullptr));
  }
}

TEST(ConfTest, ParseList) {
  const struct {
    const char *list;
    char sep;
    bool remove_whitespace;
    std::vector<std::string> expected;
  } kTests[] = {
      {"", ',', /*remove_whitespace=*/0, {""}},
      {"", ',', /*remove_whitespace=*/1, {""}},

      {" ", ',', /*remove_whitespace=*/0, {" "}},
      {" ", ',', /*remove_whitespace=*/1, {""}},

      {"hello world", ',', /*remove_whitespace=*/0, {"hello world"}},
      {"hello world", ',', /*remove_whitespace=*/1, {"hello world"}},

      {" hello world ", ',', /*remove_whitespace=*/0, {" hello world "}},
      {" hello world ", ',', /*remove_whitespace=*/1, {"hello world"}},

      {"hello,world", ',', /*remove_whitespace=*/0, {"hello", "world"}},
      {"hello,world", ',', /*remove_whitespace=*/1, {"hello", "world"}},

      {"hello,,world", ',', /*remove_whitespace=*/0, {"hello", "", "world"}},
      {"hello,,world", ',', /*remove_whitespace=*/1, {"hello", "", "world"}},

      {"\tab cd , , ef gh ",
       ',',
       /*remove_whitespace=*/0,
       {"\tab cd ", " ", " ef gh "}},
      {"\tab cd , , ef gh ",
       ',',
       /*remove_whitespace=*/1,
       {"ab cd", "", "ef gh"}},
  };
  for (const auto& t : kTests) {
    SCOPED_TRACE(t.list);
    SCOPED_TRACE(t.sep);
    SCOPED_TRACE(t.remove_whitespace);

    std::vector<std::string> result;
    auto append_to_vector = [](const char *elem, size_t len, void *arg) -> int {
      auto *vec = static_cast<std::vector<std::string> *>(arg);
      vec->push_back(std::string(elem, len));
      return 1;
    };
    ASSERT_TRUE(CONF_parse_list(t.list, t.sep, t.remove_whitespace,
                                append_to_vector, &result));
    EXPECT_EQ(result, t.expected);
  }
}

}  // namespace
BSSL_NAMESPACE_END
