// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/parse_number.h"

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

namespace net {

namespace {

// The string to number conversion functions in //base include the type in the
// name (like StringToInt64()). The following wrapper methods create a
// consistent interface to StringToXXX() that calls the appropriate //base
// version. This simplifies writing generic code with a template.

bool StringToNumber(base::StringPiece input, int32_t* output) {
  // This assumes ints are 32-bits (will fail compile if that ever changes).
  return base::StringToInt(input, output);
}

bool StringToNumber(base::StringPiece input, uint32_t* output) {
  // This assumes ints are 32-bits (will fail compile if that ever changes).
  return base::StringToUint(input, output);
}

bool StringToNumber(base::StringPiece input, int64_t* output) {
  return base::StringToInt64(input, output);
}

bool StringToNumber(base::StringPiece input, uint64_t* output) {
  return base::StringToUint64(input, output);
}

bool SetError(ParseIntError error, ParseIntError* optional_error) {
  if (optional_error)
    *optional_error = error;
  return false;
}

template <typename T>
bool ParseIntHelper(base::StringPiece input,
                    ParseIntFormat format,
                    T* output,
                    ParseIntError* optional_error) {
  // Check that the input matches the format before calling StringToNumber().
  // Numbers must start with either a digit or a negative sign.
  if (input.empty())
    return SetError(ParseIntError::FAILED_PARSE, optional_error);

  bool is_non_negative = (format == ParseIntFormat::NON_NEGATIVE ||
                          format == ParseIntFormat::STRICT_NON_NEGATIVE);
  bool is_strict = (format == ParseIntFormat::STRICT_NON_NEGATIVE ||
                    format == ParseIntFormat::STRICT_OPTIONALLY_NEGATIVE);

  bool starts_with_negative = input[0] == '-';
  bool starts_with_digit = base::IsAsciiDigit(input[0]);

  if (!starts_with_digit) {
    // The length() < 2 check catches "-". It's needed here to prevent reading
    // beyond the end of the array on line 70.
    if (is_non_negative || !starts_with_negative || input.length() < 2) {
      return SetError(ParseIntError::FAILED_PARSE, optional_error);
    }
    // If the first digit after the negative is a 0, then either the number is
    // -0 or it has an unnecessary leading 0. Either way, it violates the
    // requirements of being "strict", so fail if strict.
    if (is_strict && input[1] == '0') {
      return SetError(ParseIntError::FAILED_PARSE, optional_error);
    }
  } else {
    // Fail if the first character is a zero and the string has more than 1
    // digit.
    if (is_strict && input[0] == '0' && input.length() > 1) {
      return SetError(ParseIntError::FAILED_PARSE, optional_error);
    }
  }

  // Dispatch to the appropriate flavor of base::StringToXXX() by calling one of
  // the type-specific overloads.
  T result;
  if (StringToNumber(input, &result)) {
    *output = result;
    return true;
  }

  // Optimization: If the error is not going to be inspected, don't bother
  // calculating it.
  if (!optional_error)
    return false;

  // Set an error that distinguishes between parsing/underflow/overflow errors.
  //
  // Note that the output set by base::StringToXXX() on failure cannot be used
  // as it has ambiguity with parse errors.

  // Strip any leading negative sign off the number.
  base::StringPiece numeric_portion =
      starts_with_negative ? input.substr(1) : input;

  // Test if |numeric_portion| is a valid non-negative integer.
  if (!numeric_portion.empty() &&
      numeric_portion.find_first_not_of("0123456789") == std::string::npos) {
    // If it was, the failure must have been due to underflow/overflow.
    return SetError(starts_with_negative ? ParseIntError::FAILED_UNDERFLOW
                                         : ParseIntError::FAILED_OVERFLOW,
                    optional_error);
  }

  // Otherwise it was a mundane parsing error.
  return SetError(ParseIntError::FAILED_PARSE, optional_error);
}

}  // namespace

bool ParseInt32(base::StringPiece input,
                ParseIntFormat format,
                int32_t* output,
                ParseIntError* optional_error) {
  return ParseIntHelper(input, format, output, optional_error);
}

bool ParseInt64(base::StringPiece input,
                ParseIntFormat format,
                int64_t* output,
                ParseIntError* optional_error) {
  return ParseIntHelper(input, format, output, optional_error);
}

bool ParseUint32(base::StringPiece input,
                 ParseIntFormat format,
                 uint32_t* output,
                 ParseIntError* optional_error) {
  CHECK(format == ParseIntFormat::NON_NEGATIVE ||
        format == ParseIntFormat::STRICT_NON_NEGATIVE);
  return ParseIntHelper(input, format, output, optional_error);
}

bool ParseUint64(base::StringPiece input,
                 ParseIntFormat format,
                 uint64_t* output,
                 ParseIntError* optional_error) {
  CHECK(format == ParseIntFormat::NON_NEGATIVE ||
        format == ParseIntFormat::STRICT_NON_NEGATIVE);
  return ParseIntHelper(input, format, output, optional_error);
}

}  // namespace net
