// Copyright 2013 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.

#include <limits.h>

#include "polyfills/base/logging.h"
#include "url/url_canon.h"
#include "url/url_canon_internal.h"
#include "url/url_parse_internal.h"

namespace url {

namespace {

enum CharacterFlags {
  // Pass through unchanged, whether escaped or unescaped. This doesn't
  // actually set anything so you can't OR it to check, it's just to make the
  // table below more clear when neither ESCAPE or UNESCAPE is set.
  PASS = 0,

  // This character requires special handling in DoPartialPath. Doing this test
  // first allows us to filter out the common cases of regular characters that
  // can be directly copied.
  SPECIAL = 1,

  // This character must be escaped in the canonical output. Note that all
  // escaped chars also have the "special" bit set so that the code that looks
  // for this is triggered. Not valid with PASS or ESCAPE
  ESCAPE_BIT = 2,
  ESCAPE = ESCAPE_BIT | SPECIAL,

  // This character must be unescaped in canonical output. Not valid with
  // ESCAPE or PASS. We DON'T set the SPECIAL flag since if we encounter these
  // characters unescaped, they should just be copied.
  UNESCAPE = 4,

  // This character is disallowed in URLs. Note that the "special" bit is also
  // set to trigger handling.
  INVALID_BIT = 8,
  INVALID = INVALID_BIT | SPECIAL,
};

// This table contains one of the above flag values. Note some flags are more
// than one bits because they also turn on the "special" flag. Special is the
// only flag that may be combined with others.
//
// This table is designed to match exactly what IE does with the characters.
//
// Dot is even more special, and the escaped version is handled specially by
// IsDot. Therefore, we don't need the "escape" flag, and even the "unescape"
// bit is never handled (we just need the "special") bit.
const unsigned char kPathCharLookup[0x100] = {
//   NULL     control chars...
     INVALID, ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
//   control chars...
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
//   ' '      !        "        #        $        %        &        '        (        )        *        +        ,        -        .        /
     ESCAPE,  PASS,    ESCAPE,  ESCAPE,  PASS,    ESCAPE,  PASS,    PASS,    PASS,    PASS,    PASS,    PASS,    PASS,    UNESCAPE,SPECIAL, PASS,
//   0        1        2        3        4        5        6        7        8        9        :        ;        <        =        >        ?
     UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,PASS,    PASS,    ESCAPE,  PASS,    ESCAPE,  ESCAPE,
//   @        A        B        C        D        E        F        G        H        I        J        K        L        M        N        O
     PASS,    UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,
//   P        Q        R        S        T        U        V        W        X        Y        Z        [        \        ]        ^        _
     UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,PASS,    ESCAPE,  PASS,    ESCAPE,  UNESCAPE,
//   `        a        b        c        d        e        f        g        h        i        j        k        l        m        n        o
     ESCAPE,  UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,
//   p        q        r        s        t        u        v        w        x        y        z        {        |        }        ~        <NBSP>
     UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,UNESCAPE,ESCAPE,  ESCAPE,  ESCAPE,  UNESCAPE,ESCAPE,
//   ...all the high-bit characters are escaped
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,
     ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE,  ESCAPE};

enum DotDisposition {
  // The given dot is just part of a filename and is not special.
  NOT_A_DIRECTORY,

  // The given dot is the current directory.
  DIRECTORY_CUR,

  // The given dot is the first of a double dot that should take us up one.
  DIRECTORY_UP
};

// When the path resolver finds a dot, this function is called with the
// character following that dot to see what it is. The return value
// indicates what type this dot is (see above). This code handles the case
// where the dot is at the end of the input.
//
// |*consumed_len| will contain the number of characters in the input that
// express what we found.
//
// If the input is "../foo", |after_dot| = 1, |end| = 6, and
// at the end, |*consumed_len| = 2 for the "./" this function consumed. The
// original dot length should be handled by the caller.
template<typename CHAR>
DotDisposition ClassifyAfterDot(const CHAR* spec, int after_dot,
                                int end, int* consumed_len) {
  if (after_dot == end) {
    // Single dot at the end.
    *consumed_len = 0;
    return DIRECTORY_CUR;
  }
  if (IsURLSlash(spec[after_dot])) {
    // Single dot followed by a slash.
    *consumed_len = 1;  // Consume the slash
    return DIRECTORY_CUR;
  }

  int second_dot_len = IsDot(spec, after_dot, end);
  if (second_dot_len) {
    int after_second_dot = after_dot + second_dot_len;
    if (after_second_dot == end) {
      // Double dot at the end.
      *consumed_len = second_dot_len;
      return DIRECTORY_UP;
    }
    if (IsURLSlash(spec[after_second_dot])) {
      // Double dot followed by a slash.
      *consumed_len = second_dot_len + 1;
      return DIRECTORY_UP;
    }
  }

  // The dots are followed by something else, not a directory.
  *consumed_len = 0;
  return NOT_A_DIRECTORY;
}

// Rewinds the output to the previous slash. It is assumed that the output
// ends with a slash and this doesn't count (we call this when we are
// appending directory paths, so the previous path component has and ending
// slash).
//
// This will stop at the first slash (assumed to be at position
// |path_begin_in_output| and not go any higher than that. Some web pages
// do ".." too many times, so we need to handle that brokenness.
//
// It searches for a literal slash rather than including a backslash as well
// because it is run only on the canonical output.
//
// The output is guaranteed to end in a slash when this function completes.
void BackUpToPreviousSlash(int path_begin_in_output,
                           CanonOutput* output) {
  GURL_DCHECK(output->length() > 0);

  int i = output->length() - 1;
  GURL_DCHECK(output->at(i) == '/');
  if (i == path_begin_in_output)
    return;  // We're at the first slash, nothing to do.

  // Now back up (skipping the trailing slash) until we find another slash.
  i--;
  while (output->at(i) != '/' && i > path_begin_in_output)
    i--;

  // Now shrink the output to just include that last slash we found.
  output->set_length(i + 1);
}

// Looks for problematic nested escape sequences and escapes the output as
// needed to ensure they can't be misinterpreted.
//
// Our concern is that in input escape sequence that's invalid because it
// contains nested escape sequences might look valid once those are unescaped.
// For example, "%%300" is not a valid escape sequence, but after unescaping the
// inner "%30" this becomes "%00" which is valid.  Leaving this in the output
// string can result in callers re-canonicalizing the string and unescaping this
// sequence, thus resulting in something fundamentally different than the
// original input here.  This can cause a variety of problems.
//
// This function is called after we've just unescaped a sequence that's within
// two output characters of a previous '%' that we know didn't begin a valid
// escape sequence in the input string.  We look for whether the output is going
// to turn into a valid escape sequence, and if so, convert the initial '%' into
// an escaped "%25" so the output can't be misinterpreted.
//
// |spec| is the input string we're canonicalizing.
// |next_input_index| is the index of the next unprocessed character in |spec|.
// |input_len| is the length of |spec|.
// |last_invalid_percent_index| is the index in |output| of a previously-seen
// '%' character.  The caller knows this '%' character isn't followed by a valid
// escape sequence in the input string.
// |output| is the canonicalized output thus far.  The caller guarantees this
// ends with a '%' followed by one or two characters, and the '%' is the one
// pointed to by |last_invalid_percent_index|.  The last character in the string
// was just unescaped.
template<typename CHAR>
void CheckForNestedEscapes(const CHAR* spec,
                           int next_input_index,
                           int input_len,
                           int last_invalid_percent_index,
                           CanonOutput* output) {
  const int length = output->length();
  const char last_unescaped_char = output->at(length - 1);

  // If |output| currently looks like "%c", we need to try appending the next
  // input character to see if this will result in a problematic escape
  // sequence.  Note that this won't trigger on the first nested escape of a
  // two-escape sequence like "%%30%30" -- we'll allow the conversion to
  // "%0%30" -- but the second nested escape will be caught by this function
  // when it's called again in that case.
  const bool append_next_char = last_invalid_percent_index == length - 2;
  if (append_next_char) {
    // If the input doesn't contain a 7-bit character next, this case won't be a
    // problem.
    if ((next_input_index == input_len) || (spec[next_input_index] >= 0x80))
      return;
    output->push_back(static_cast<char>(spec[next_input_index]));
  }

  // Now output ends like "%cc".  Try to unescape this.
  int begin = last_invalid_percent_index;
  unsigned char temp;
  if (DecodeEscaped(output->data(), &begin, output->length(), &temp)) {
    // New escape sequence found.  Overwrite the characters following the '%'
    // with "25", and push_back() the one or two characters that were following
    // the '%' when we were called.
    if (!append_next_char)
      output->push_back(output->at(last_invalid_percent_index + 1));
    output->set(last_invalid_percent_index + 1, '2');
    output->set(last_invalid_percent_index + 2, '5');
    output->push_back(last_unescaped_char);
  } else if (append_next_char) {
    // Not a valid escape sequence, but we still need to undo appending the next
    // source character so the caller can process it normally.
    output->set_length(length);
  }
}

// Appends the given path to the output. It assumes that if the input path
// starts with a slash, it should be copied to the output. If no path has
// already been appended to the output (the case when not resolving
// relative URLs), the path should begin with a slash.
//
// If there are already path components (this mode is used when appending
// relative paths for resolving), it assumes that the output already has
// a trailing slash and that if the input begins with a slash, it should be
// copied to the output.
//
// We do not collapse multiple slashes in a row to a single slash. It seems
// no web browsers do this, and we don't want incompatibilities, even though
// it would be correct for most systems.
template<typename CHAR, typename UCHAR>
bool DoPartialPath(const CHAR* spec,
                   const Component& path,
                   int path_begin_in_output,
                   CanonOutput* output) {
  int end = path.end();

  // We use this variable to minimize the amount of work done when unescaping --
  // we'll only call CheckForNestedEscapes() when this points at one of the last
  // couple of characters in |output|.
  int last_invalid_percent_index = INT_MIN;

  bool success = true;
  for (int i = path.begin; i < end; i++) {
    UCHAR uch = static_cast<UCHAR>(spec[i]);
    if (sizeof(CHAR) > 1 && uch >= 0x80) {
      // We only need to test wide input for having non-ASCII characters. For
      // narrow input, we'll always just use the lookup table. We don't try to
      // do anything tricky with decoding/validating UTF-8. This function will
      // read one or two UTF-16 characters and append the output as UTF-8. This
      // call will be removed in 8-bit mode.
      success &= AppendUTF8EscapedChar(spec, &i, end, output);
    } else {
      // Normal ASCII character or 8-bit input, use the lookup table.
      unsigned char out_ch = static_cast<unsigned char>(uch);
      unsigned char flags = kPathCharLookup[out_ch];
      if (flags & SPECIAL) {
        // Needs special handling of some sort.
        int dotlen;
        if ((dotlen = IsDot(spec, i, end)) > 0) {
          // See if this dot was preceded by a slash in the output. We
          // assume that when canonicalizing paths, they will always
          // start with a slash and not a dot, so we don't have to
          // bounds check the output.
          //
          // Note that we check this in the case of dots so we don't have to
          // special case slashes. Since slashes are much more common than
          // dots, this actually increases performance measurably (though
          // slightly).
          GURL_DCHECK(output->length() > path_begin_in_output);
          if (output->length() > path_begin_in_output &&
              output->at(output->length() - 1) == '/') {
            // Slash followed by a dot, check to see if this is means relative
            int consumed_len;
            switch (ClassifyAfterDot<CHAR>(spec, i + dotlen, end,
                                           &consumed_len)) {
              case NOT_A_DIRECTORY:
                // Copy the dot to the output, it means nothing special.
                output->push_back('.');
                i += dotlen - 1;
                break;
              case DIRECTORY_CUR:  // Current directory, just skip the input.
                i += dotlen + consumed_len - 1;
                break;
              case DIRECTORY_UP:
                BackUpToPreviousSlash(path_begin_in_output, output);
                i += dotlen + consumed_len - 1;
                break;
            }
          } else {
            // This dot is not preceded by a slash, it is just part of some
            // file name.
            output->push_back('.');
            i += dotlen - 1;
          }

        } else if (out_ch == '\\') {
          // Convert backslashes to forward slashes
          output->push_back('/');

        } else if (out_ch == '%') {
          // Handle escape sequences.
          unsigned char unescaped_value;
          if (DecodeEscaped(spec, &i, end, &unescaped_value)) {
            // Valid escape sequence, see if we keep, reject, or unescape it.
            // Note that at this point DecodeEscape() will have advanced |i| to
            // the last character of the escape sequence.
            char unescaped_flags = kPathCharLookup[unescaped_value];

            if (unescaped_flags & UNESCAPE) {
              // This escaped value shouldn't be escaped.  Try to copy it.
              output->push_back(unescaped_value);
              // If we just unescaped a value within 2 output characters of the
              // '%' from a previously-detected invalid escape sequence, we
              // might have an input string with problematic nested escape
              // sequences; detect and fix them.
              if (last_invalid_percent_index >= (output->length() - 3)) {
                CheckForNestedEscapes(spec, i + 1, end,
                                      last_invalid_percent_index, output);
              }
            } else {
              // Either this is an invalid escaped character, or it's a valid
              // escaped character we should keep escaped.  In the first case we
              // should just copy it exactly and remember the error.  In the
              // second we also copy exactly in case the server is sensitive to
              // changing the case of any hex letters.
              output->push_back('%');
              output->push_back(static_cast<char>(spec[i - 1]));
              output->push_back(static_cast<char>(spec[i]));
              if (unescaped_flags & INVALID_BIT)
                success = false;
            }
          } else {
            // Invalid escape sequence. IE7+ rejects any URLs with such
            // sequences, while other browsers pass them through unchanged. We
            // use the permissive behavior.
            // TODO(brettw): Consider testing IE's strict behavior, which would
            // allow removing the code to handle nested escapes above.
            last_invalid_percent_index = output->length();
            output->push_back('%');
          }

        } else if (flags & INVALID_BIT) {
          // For NULLs, etc. fail.
          AppendEscapedChar(out_ch, output);
          success = false;

        } else if (flags & ESCAPE_BIT) {
          // This character should be escaped.
          AppendEscapedChar(out_ch, output);
        }
      } else {
        // Nothing special about this character, just append it.
        output->push_back(out_ch);
      }
    }
  }
  return success;
}

template<typename CHAR, typename UCHAR>
bool DoPath(const CHAR* spec,
            const Component& path,
            CanonOutput* output,
            Component* out_path) {
  bool success = true;
  out_path->begin = output->length();
  if (path.len > 0) {
    // Write out an initial slash if the input has none. If we just parse a URL
    // and then canonicalize it, it will of course have a slash already. This
    // check is for the replacement and relative URL resolving cases of file
    // URLs.
    if (!IsURLSlash(spec[path.begin]))
      output->push_back('/');

    success = DoPartialPath<CHAR, UCHAR>(spec, path, out_path->begin, output);
  } else {
    // No input, canonical path is a slash.
    output->push_back('/');
  }
  out_path->len = output->length() - out_path->begin;
  return success;
}

}  // namespace

bool CanonicalizePath(const char* spec,
                      const Component& path,
                      CanonOutput* output,
                      Component* out_path) {
  return DoPath<char, unsigned char>(spec, path, output, out_path);
}

bool CanonicalizePath(const gurl_base::char16* spec,
                      const Component& path,
                      CanonOutput* output,
                      Component* out_path) {
  return DoPath<gurl_base::char16, gurl_base::char16>(spec, path, output, out_path);
}

bool CanonicalizePartialPath(const char* spec,
                             const Component& path,
                             int path_begin_in_output,
                             CanonOutput* output) {
  return DoPartialPath<char, unsigned char>(spec, path, path_begin_in_output,
                                            output);
}

bool CanonicalizePartialPath(const gurl_base::char16* spec,
                             const Component& path,
                             int path_begin_in_output,
                             CanonOutput* output) {
  return DoPartialPath<gurl_base::char16, gurl_base::char16>(spec, path,
                                                   path_begin_in_output,
                                                   output);
}

}  // namespace url
