// 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 "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) {
  DCHECK(output->length() > 0);

  int i = output->length() - 1;
  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).
          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 base::char16* spec,
                      const Component& path,
                      CanonOutput* output,
                      Component* out_path) {
  return DoPath<base::char16, 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 base::char16* spec,
                             const Component& path,
                             int path_begin_in_output,
                             CanonOutput* output) {
  return DoPartialPath<base::char16, base::char16>(spec, path,
                                                   path_begin_in_output,
                                                   output);
}

}  // namespace url
