// Copyright (c) 2012 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.

// Portions of this code based on Mozilla:
//   (netwerk/cookie/src/nsCookieService.cpp)
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 2003
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Daniel Witte (dwitte@stanford.edu)
 *   Michiel van Leeuwen (mvl@exedo.nl)
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "net/cookies/parsed_cookie.h"

#include "base/logging.h"
#include "base/strings/string_util.h"

namespace {

const char kPathTokenName[] = "path";
const char kDomainTokenName[] = "domain";
const char kExpiresTokenName[] = "expires";
const char kMaxAgeTokenName[] = "max-age";
const char kSecureTokenName[] = "secure";
const char kHttpOnlyTokenName[] = "httponly";
const char kFirstPartyOnlyTokenName[] = "first-party-only";
const char kPriorityTokenName[] = "priority";

const char kTerminator[] = "\n\r\0";
const int kTerminatorLen = sizeof(kTerminator) - 1;
const char kWhitespace[] = " \t";
const char kValueSeparator[] = ";";
const char kTokenSeparator[] = ";=";

// Returns true if |c| occurs in |chars|
// TODO(erikwright): maybe make this take an iterator, could check for end also?
inline bool CharIsA(const char c, const char* chars) {
  return strchr(chars, c) != NULL;
}
// Seek the iterator to the first occurrence of a character in |chars|.
// Returns true if it hit the end, false otherwise.
inline bool SeekTo(std::string::const_iterator* it,
                   const std::string::const_iterator& end,
                   const char* chars) {
  for (; *it != end && !CharIsA(**it, chars); ++(*it)) {
  }
  return *it == end;
}
// Seek the iterator to the first occurrence of a character not in |chars|.
// Returns true if it hit the end, false otherwise.
inline bool SeekPast(std::string::const_iterator* it,
                     const std::string::const_iterator& end,
                     const char* chars) {
  for (; *it != end && CharIsA(**it, chars); ++(*it)) {
  }
  return *it == end;
}
inline bool SeekBackPast(std::string::const_iterator* it,
                         const std::string::const_iterator& end,
                         const char* chars) {
  for (; *it != end && CharIsA(**it, chars); --(*it)) {
  }
  return *it == end;
}

// Validate whether |value| is a valid token according to [RFC2616],
// Section 2.2.
bool IsValidToken(const std::string& value) {
  if (value.empty())
    return false;

  // Check that |value| has no separators.
  std::string separators = "()<>@,;:\\\"/[]?={} \t";
  if (value.find_first_of(separators) != std::string::npos)
    return false;

  // Check that |value| has no CTLs.
  for (std::string::const_iterator i = value.begin(); i != value.end(); ++i) {
    if ((*i >= 0 && *i <= 31) || *i >= 127)
      return false;
  }

  return true;
}

// Validate value, which may be according to RFC 6265
// cookie-value      = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE )
// cookie-octet      = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E
//                      ; US-ASCII characters excluding CTLs,
//                      ; whitespace DQUOTE, comma, semicolon,
//                      ; and backslash
bool IsValidCookieValue(const std::string& value) {
  // Number of characters to skip in validation at beginning and end of string.
  size_t skip = 0;
  if (value.size() >= 2 && *value.begin() == '"' && *(value.end() - 1) == '"')
    skip = 1;
  for (std::string::const_iterator i = value.begin() + skip;
       i != value.end() - skip; ++i) {
    bool valid_octet =
        (*i == 0x21 || (*i >= 0x23 && *i <= 0x2B) ||
         (*i >= 0x2D && *i <= 0x3A) || (*i >= 0x3C && *i <= 0x5B) ||
         (*i >= 0x5D && *i <= 0x7E));
    if (!valid_octet)
      return false;
  }
  return true;
}

bool IsControlCharacter(unsigned char c) {
  return c <= 31;
}

bool IsValidCookieAttributeValue(const std::string& value) {
  // The greatest common denominator of cookie attribute values is
  // <any CHAR except CTLs or ";"> according to RFC 6265.
  for (std::string::const_iterator i = value.begin(); i != value.end(); ++i) {
    if (IsControlCharacter(*i) || *i == ';')
      return false;
  }
  return true;
}

}  // namespace

namespace net {

ParsedCookie::ParsedCookie(const std::string& cookie_line)
    : path_index_(0),
      domain_index_(0),
      expires_index_(0),
      maxage_index_(0),
      secure_index_(0),
      httponly_index_(0),
      firstpartyonly_index_(0),
      priority_index_(0) {
  if (cookie_line.size() > kMaxCookieSize) {
    VLOG(1) << "Not parsing cookie, too large: " << cookie_line.size();
    return;
  }

  ParseTokenValuePairs(cookie_line);
  if (!pairs_.empty())
    SetupAttributes();
}

ParsedCookie::~ParsedCookie() {
}

bool ParsedCookie::IsValid() const {
  return !pairs_.empty();
}

CookiePriority ParsedCookie::Priority() const {
  return (priority_index_ == 0)
             ? COOKIE_PRIORITY_DEFAULT
             : StringToCookiePriority(pairs_[priority_index_].second);
}

bool ParsedCookie::SetName(const std::string& name) {
  if (!IsValidToken(name))
    return false;
  if (pairs_.empty())
    pairs_.push_back(std::make_pair("", ""));
  pairs_[0].first = name;
  return true;
}

bool ParsedCookie::SetValue(const std::string& value) {
  if (!IsValidCookieValue(value))
    return false;
  if (pairs_.empty())
    pairs_.push_back(std::make_pair("", ""));
  pairs_[0].second = value;
  return true;
}

bool ParsedCookie::SetPath(const std::string& path) {
  return SetString(&path_index_, kPathTokenName, path);
}

bool ParsedCookie::SetDomain(const std::string& domain) {
  return SetString(&domain_index_, kDomainTokenName, domain);
}

bool ParsedCookie::SetExpires(const std::string& expires) {
  return SetString(&expires_index_, kExpiresTokenName, expires);
}

bool ParsedCookie::SetMaxAge(const std::string& maxage) {
  return SetString(&maxage_index_, kMaxAgeTokenName, maxage);
}

bool ParsedCookie::SetIsSecure(bool is_secure) {
  return SetBool(&secure_index_, kSecureTokenName, is_secure);
}

bool ParsedCookie::SetIsHttpOnly(bool is_http_only) {
  return SetBool(&httponly_index_, kHttpOnlyTokenName, is_http_only);
}

bool ParsedCookie::SetIsFirstPartyOnly(bool is_first_party_only) {
  return SetBool(&firstpartyonly_index_, kFirstPartyOnlyTokenName,
                 is_first_party_only);
}

bool ParsedCookie::SetPriority(const std::string& priority) {
  return SetString(&priority_index_, kPriorityTokenName, priority);
}

std::string ParsedCookie::ToCookieLine() const {
  std::string out;
  for (PairList::const_iterator it = pairs_.begin(); it != pairs_.end(); ++it) {
    if (!out.empty())
      out.append("; ");
    out.append(it->first);
    if (it->first != kSecureTokenName && it->first != kHttpOnlyTokenName &&
        it->first != kFirstPartyOnlyTokenName) {
      out.append("=");
      out.append(it->second);
    }
  }
  return out;
}

std::string::const_iterator ParsedCookie::FindFirstTerminator(
    const std::string& s) {
  std::string::const_iterator end = s.end();
  size_t term_pos = s.find_first_of(std::string(kTerminator, kTerminatorLen));
  if (term_pos != std::string::npos) {
    // We found a character we should treat as an end of string.
    end = s.begin() + term_pos;
  }
  return end;
}

bool ParsedCookie::ParseToken(std::string::const_iterator* it,
                              const std::string::const_iterator& end,
                              std::string::const_iterator* token_start,
                              std::string::const_iterator* token_end) {
  DCHECK(it && token_start && token_end);
  std::string::const_iterator token_real_end;

  // Seek past any whitespace before the "token" (the name).
  // token_start should point at the first character in the token
  if (SeekPast(it, end, kWhitespace))
    return false;  // No token, whitespace or empty.
  *token_start = *it;

  // Seek over the token, to the token separator.
  // token_real_end should point at the token separator, i.e. '='.
  // If it == end after the seek, we probably have a token-value.
  SeekTo(it, end, kTokenSeparator);
  token_real_end = *it;

  // Ignore any whitespace between the token and the token separator.
  // token_end should point after the last interesting token character,
  // pointing at either whitespace, or at '=' (and equal to token_real_end).
  if (*it != *token_start) {  // We could have an empty token name.
    --(*it);                  // Go back before the token separator.
    // Skip over any whitespace to the first non-whitespace character.
    SeekBackPast(it, *token_start, kWhitespace);
    // Point after it.
    ++(*it);
  }
  *token_end = *it;

  // Seek us back to the end of the token.
  *it = token_real_end;
  return true;
}

void ParsedCookie::ParseValue(std::string::const_iterator* it,
                              const std::string::const_iterator& end,
                              std::string::const_iterator* value_start,
                              std::string::const_iterator* value_end) {
  DCHECK(it && value_start && value_end);

  // Seek past any whitespace that might in-between the token and value.
  SeekPast(it, end, kWhitespace);
  // value_start should point at the first character of the value.
  *value_start = *it;

  // Just look for ';' to terminate ('=' allowed).
  // We can hit the end, maybe they didn't terminate.
  SeekTo(it, end, kValueSeparator);

  // Will be pointed at the ; seperator or the end.
  *value_end = *it;

  // Ignore any unwanted whitespace after the value.
  if (*value_end != *value_start) {  // Could have an empty value
    --(*value_end);
    SeekBackPast(value_end, *value_start, kWhitespace);
    ++(*value_end);
  }
}

std::string ParsedCookie::ParseTokenString(const std::string& token) {
  std::string::const_iterator it = token.begin();
  std::string::const_iterator end = FindFirstTerminator(token);

  std::string::const_iterator token_start, token_end;
  if (ParseToken(&it, end, &token_start, &token_end))
    return std::string(token_start, token_end);
  return std::string();
}

std::string ParsedCookie::ParseValueString(const std::string& value) {
  std::string::const_iterator it = value.begin();
  std::string::const_iterator end = FindFirstTerminator(value);

  std::string::const_iterator value_start, value_end;
  ParseValue(&it, end, &value_start, &value_end);
  return std::string(value_start, value_end);
}

// Parse all token/value pairs and populate pairs_.
void ParsedCookie::ParseTokenValuePairs(const std::string& cookie_line) {
  pairs_.clear();

  // Ok, here we go.  We should be expecting to be starting somewhere
  // before the cookie line, not including any header name...
  std::string::const_iterator start = cookie_line.begin();
  std::string::const_iterator it = start;

  // TODO(erikwright): Make sure we're stripping \r\n in the network code.
  // Then we can log any unexpected terminators.
  std::string::const_iterator end = FindFirstTerminator(cookie_line);

  for (int pair_num = 0; pair_num < kMaxPairs && it != end; ++pair_num) {
    TokenValuePair pair;

    std::string::const_iterator token_start, token_end;
    if (!ParseToken(&it, end, &token_start, &token_end))
      break;

    if (it == end || *it != '=') {
      // We have a token-value, we didn't have any token name.
      if (pair_num == 0) {
        // For the first time around, we want to treat single values
        // as a value with an empty name. (Mozilla bug 169091).
        // IE seems to also have this behavior, ex "AAA", and "AAA=10" will
        // set 2 different cookies, and setting "BBB" will then replace "AAA".
        pair.first = "";
        // Rewind to the beginning of what we thought was the token name,
        // and let it get parsed as a value.
        it = token_start;
      } else {
        // Any not-first attribute we want to treat a value as a
        // name with an empty value...  This is so something like
        // "secure;" will get parsed as a Token name, and not a value.
        pair.first = std::string(token_start, token_end);
      }
    } else {
      // We have a TOKEN=VALUE.
      pair.first = std::string(token_start, token_end);
      ++it;  // Skip past the '='.
    }

    // OK, now try to parse a value.
    std::string::const_iterator value_start, value_end;
    ParseValue(&it, end, &value_start, &value_end);

    // OK, we're finished with a Token/Value.
    pair.second = std::string(value_start, value_end);

    // From RFC2109: "Attributes (names) (attr) are case-insensitive."
    if (pair_num != 0)
      base::StringToLowerASCII(&pair.first);
    // Ignore Set-Cookie directives contaning control characters. See
    // http://crbug.com/238041.
    if (!IsValidCookieAttributeValue(pair.first) ||
        !IsValidCookieAttributeValue(pair.second)) {
      pairs_.clear();
      break;
    }

    pairs_.push_back(pair);

    // We've processed a token/value pair, we're either at the end of
    // the string or a ValueSeparator like ';', which we want to skip.
    if (it != end)
      ++it;
  }
}

void ParsedCookie::SetupAttributes() {
  // Ignore Set-Cookie directive where name and value are both empty.
  if (pairs_[0].first.empty() && pairs_[0].second.empty()) {
    pairs_.clear();
    return;
  }

  // We skip over the first token/value, the user supplied one.
  for (size_t i = 1; i < pairs_.size(); ++i) {
    if (pairs_[i].first == kPathTokenName) {
      path_index_ = i;
    } else if (pairs_[i].first == kDomainTokenName) {
      domain_index_ = i;
    } else if (pairs_[i].first == kExpiresTokenName) {
      expires_index_ = i;
    } else if (pairs_[i].first == kMaxAgeTokenName) {
      maxage_index_ = i;
    } else if (pairs_[i].first == kSecureTokenName) {
      secure_index_ = i;
    } else if (pairs_[i].first == kHttpOnlyTokenName) {
      httponly_index_ = i;
    } else if (pairs_[i].first == kFirstPartyOnlyTokenName) {
      firstpartyonly_index_ = i;
    } else if (pairs_[i].first == kPriorityTokenName) {
      priority_index_ = i;
    } else {
      /* some attribute we don't know or don't care about. */
    }
  }
}

bool ParsedCookie::SetString(size_t* index,
                             const std::string& key,
                             const std::string& value) {
  if (value.empty()) {
    ClearAttributePair(*index);
    return true;
  } else {
    return SetAttributePair(index, key, value);
  }
}

bool ParsedCookie::SetBool(size_t* index, const std::string& key, bool value) {
  if (!value) {
    ClearAttributePair(*index);
    return true;
  } else {
    return SetAttributePair(index, key, std::string());
  }
}

bool ParsedCookie::SetAttributePair(size_t* index,
                                    const std::string& key,
                                    const std::string& value) {
  if (!(IsValidToken(key) && IsValidCookieAttributeValue(value)))
    return false;
  if (!IsValid())
    return false;
  if (*index) {
    pairs_[*index].second = value;
  } else {
    pairs_.push_back(std::make_pair(key, value));
    *index = pairs_.size() - 1;
  }
  return true;
}

void ParsedCookie::ClearAttributePair(size_t index) {
  // The first pair (name/value of cookie at pairs_[0]) cannot be cleared.
  // Cookie attributes that don't have a value at the moment, are represented
  // with an index being equal to 0.
  if (index == 0)
    return;

  size_t* indexes[] = {&path_index_,
                       &domain_index_,
                       &expires_index_,
                       &maxage_index_,
                       &secure_index_,
                       &httponly_index_,
                       &firstpartyonly_index_,
                       &priority_index_};
  for (size_t i = 0; i < arraysize(indexes); ++i) {
    if (*indexes[i] == index)
      *indexes[i] = 0;
    else if (*indexes[i] > index)
      --*indexes[i];
  }
  pairs_.erase(pairs_.begin() + index);
}

}  // namespace
