// Copyright 2017 The Chromium Authors. All rights reserved.
// Copyright (C) 2018 Apple Inc. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config.h"
#include "CBORReader.h"

#if ENABLE(WEB_AUTHN)

#include "CBORBinary.h"
#include <limits>
#include <utility>

namespace cbor {

namespace {

CBORValue::Type getMajorType(uint8_t initialDataByte)
{
    return static_cast<CBORValue::Type>((initialDataByte & constants::kMajorTypeMask) >> constants::kMajorTypeBitShift);
}

uint8_t getAdditionalInfo(uint8_t initialDataByte)
{
    return initialDataByte & constants::kAdditionalInformationMask;
}

// Error messages that correspond to each of the error codes.
const char kNoError[] = "Successfully deserialized to a CBOR value.";
const char kUnsupportedMajorType[] = "Unsupported major type.";
const char kUnknownAdditionalInfo[] = "Unknown additional info format in the first byte.";
const char kIncompleteCBORData[] = "Prematurely terminated CBOR data byte array.";
const char kIncorrectMapKeyType[] = "Map keys other than utf-8 encoded strings are not allowed.";
const char kTooMuchNesting[] = "Too much nesting.";
const char kInvalidUTF8[] = "String encoding other than utf8 are not allowed.";
const char kExtraneousData[] = "Trailing data bytes are not allowed.";
const char kDuplicateKey[] = "Duplicate map keys are not allowed.";
const char kMapKeyOutOfOrder[] = "Map keys must be sorted by byte length and then by byte-wise lexical order.";
const char kNonMinimalCBOREncoding[] = "Unsigned integers must be encoded with minimum number of bytes.";
const char kUnsupportedSimpleValue[] = "Unsupported or unassigned simple value.";
const char kUnsupportedFloatingPointValue[] = "Floating point numbers are not supported.";
const char kOutOfRangeIntegerValue[] = "Integer values must be between INT64_MIN and INT64_MAX.";

} // namespace

CBORReader::CBORReader(Bytes::const_iterator it, Bytes::const_iterator end)
    : m_it(it)
    , m_end(end)
    , m_errorCode(DecoderError::CBORNoError)
{
}

CBORReader::~CBORReader()
{
}

// static
Optional<CBORValue> CBORReader::read(const Bytes& data, DecoderError* errorCodeOut, int maxNestingLevel)
{
    CBORReader reader(data.begin(), data.end());
    Optional<CBORValue> decodedCbor = reader.decodeCBOR(maxNestingLevel);

    if (decodedCbor)
        reader.checkExtraneousData();
    if (errorCodeOut)
        *errorCodeOut = reader.getErrorCode();

    if (reader.getErrorCode() != DecoderError::CBORNoError)
        return WTF::nullopt;
    return decodedCbor;
}

Optional<CBORValue> CBORReader::decodeCBOR(int maxNestingLevel)
{
    if (maxNestingLevel < 0 || maxNestingLevel > kCBORMaxDepth) {
        m_errorCode = DecoderError::TooMuchNesting;
        return WTF::nullopt;
    }

    if (!canConsume(1)) {
        m_errorCode = DecoderError::IncompleteCBORData;
        return WTF::nullopt;
    }

    const uint8_t initialByte = *m_it++;
    const auto major_type = getMajorType(initialByte);
    const uint8_t additionalInfo = getAdditionalInfo(initialByte);

    uint64_t value;
    if (!readVariadicLengthInteger(additionalInfo, &value))
        return WTF::nullopt;

    switch (major_type) {
    case CBORValue::Type::Unsigned:
        return decodeValueToUnsigned(value);
    case CBORValue::Type::Negative:
        return decodeValueToNegative(value);
    case CBORValue::Type::ByteString:
        return readBytes(value);
    case CBORValue::Type::String:
        return readString(value);
    case CBORValue::Type::Array:
        return readCBORArray(value, maxNestingLevel);
    case CBORValue::Type::Map:
        return readCBORMap(value, maxNestingLevel);
    case CBORValue::Type::SimpleValue:
        return readSimpleValue(additionalInfo, value);
    case CBORValue::Type::None:
        break;
    }

    m_errorCode = DecoderError::UnsupportedMajorType;
    return WTF::nullopt;
}

bool CBORReader::readVariadicLengthInteger(uint8_t additionalInfo, uint64_t* value)
{
    uint8_t additionalBytes = 0;
    if (additionalInfo < 24) {
        *value = additionalInfo;
        return true;
    }

    if (additionalInfo == 24)
        additionalBytes = 1;
    else if (additionalInfo == 25)
        additionalBytes = 2;
    else if (additionalInfo == 26)
        additionalBytes = 4;
    else if (additionalInfo == 27)
        additionalBytes = 8;
    else {
        m_errorCode = DecoderError::UnknownAdditionalInfo;
        return false;
    }

    if (!canConsume(additionalBytes)) {
        m_errorCode = DecoderError::IncompleteCBORData;
        return false;
    }

    uint64_t intData = 0;
    for (uint8_t i = 0; i < additionalBytes; ++i) {
        intData <<= 8;
        intData |= *m_it++;
    }

    *value = intData;
    return checkMinimalEncoding(additionalBytes, intData);
}

Optional<CBORValue> CBORReader::decodeValueToNegative(uint64_t value)
{
    if (value > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
        m_errorCode = DecoderError::OutOfRangeIntegerValue;
        return WTF::nullopt;
    }
    return CBORValue(-static_cast<int64_t>(value) - 1);
}

Optional<CBORValue> CBORReader::decodeValueToUnsigned(uint64_t value)
{
    if (value > static_cast<uint64_t>(std::numeric_limits<int64_t>::max())) {
        m_errorCode = DecoderError::OutOfRangeIntegerValue;
        return WTF::nullopt;
    }
    return CBORValue(static_cast<int64_t>(value));
}

Optional<CBORValue> CBORReader::readSimpleValue(uint8_t additionalInfo, uint64_t value)
{
    // Floating point numbers are not supported.
    if (additionalInfo > 24 && additionalInfo < 28) {
        m_errorCode = DecoderError::UnsupportedFloatingPointValue;
        return WTF::nullopt;
    }

    ASSERT(value <= 255u);
    CBORValue::SimpleValue possiblyUnsupportedSimpleValue = static_cast<CBORValue::SimpleValue>(static_cast<int>(value));
    switch (possiblyUnsupportedSimpleValue) {
    case CBORValue::SimpleValue::FalseValue:
    case CBORValue::SimpleValue::TrueValue:
    case CBORValue::SimpleValue::NullValue:
    case CBORValue::SimpleValue::Undefined:
        return CBORValue(possiblyUnsupportedSimpleValue);
    }

    m_errorCode = DecoderError::UnsupportedSimpleValue;
    return WTF::nullopt;
}

Optional<CBORValue> CBORReader::readString(uint64_t numBytes)
{
    if (!canConsume(numBytes)) {
        m_errorCode = DecoderError::IncompleteCBORData;
        return WTF::nullopt;
    }

    ASSERT(numBytes <= std::numeric_limits<size_t>::max());
    String cborString = String::fromUTF8(m_it, static_cast<size_t>(numBytes));
    m_it += numBytes;

    // Invalid UTF8 bytes produce an empty WTFString.
    // Not to confuse it with an actual empty WTFString.
    if (!numBytes || hasValidUTF8Format(cborString))
        return CBORValue(WTFMove(cborString));
    return WTF::nullopt;
}

Optional<CBORValue> CBORReader::readBytes(uint64_t numBytes)
{
    if (!canConsume(numBytes)) {
        m_errorCode = DecoderError::IncompleteCBORData;
        return WTF::nullopt;
    }

    Bytes cborByteString;
    ASSERT(numBytes <= std::numeric_limits<size_t>::max());
    cborByteString.append(m_it, static_cast<size_t>(numBytes));
    m_it += numBytes;

    return CBORValue(WTFMove(cborByteString));
}

Optional<CBORValue> CBORReader::readCBORArray(uint64_t length, int maxNestingLevel)
{
    CBORValue::ArrayValue cborArray;
    while (length-- > 0) {
        Optional<CBORValue> cborElement = decodeCBOR(maxNestingLevel - 1);
        if (!cborElement)
            return WTF::nullopt;
        cborArray.append(WTFMove(cborElement.value()));
    }
    return CBORValue(WTFMove(cborArray));
}

Optional<CBORValue> CBORReader::readCBORMap(uint64_t length, int maxNestingLevel)
{
    CBORValue::MapValue cborMap;
    while (length-- > 0) {
        Optional<CBORValue> key = decodeCBOR(maxNestingLevel - 1);
        Optional<CBORValue> value = decodeCBOR(maxNestingLevel - 1);
        if (!key || !value)
            return WTF::nullopt;

        // Only CBOR maps with integer or string type keys are allowed.
        if (key.value().type() != CBORValue::Type::String && key.value().type() != CBORValue::Type::Unsigned) {
            m_errorCode = DecoderError::IncorrectMapKeyType;
            return WTF::nullopt;
        }
        if (!checkDuplicateKey(key.value(), cborMap) || !checkOutOfOrderKey(key.value(), cborMap))
            return WTF::nullopt;

        cborMap.emplace(std::make_pair(WTFMove(key.value()), WTFMove(value.value())));
    }
    return CBORValue(WTFMove(cborMap));
}

bool CBORReader::canConsume(uint64_t bytes)
{
    if (static_cast<uint64_t>(std::distance(m_it, m_end)) >= bytes)
        return true;
    m_errorCode = DecoderError::IncompleteCBORData;
    return false;
}

bool CBORReader::checkMinimalEncoding(uint8_t additionalBytes, uint64_t uintData)
{
    if ((additionalBytes == 1 && uintData < 24) || uintData <= (1ULL << 8 * (additionalBytes >> 1)) - 1) {
        m_errorCode = DecoderError::NonMinimalCBOREncoding;
        return false;
    }
    return true;
}

void CBORReader::checkExtraneousData()
{
    if (m_it != m_end)
        m_errorCode = DecoderError::ExtraneousData;
}

bool CBORReader::checkDuplicateKey(const CBORValue& newKey, const CBORValue::MapValue& map)
{
    if (map.find(newKey) != map.end()) {
        m_errorCode = DecoderError::DuplicateKey;
        return false;
    }
    return true;
}

bool CBORReader::hasValidUTF8Format(const String& stringData)
{
    // Invalid UTF8 bytes produce an empty WTFString.
    if (stringData.isEmpty()) {
        m_errorCode = DecoderError::InvalidUTF8;
        return false;
    }
    return true;
}

bool CBORReader::checkOutOfOrderKey(const CBORValue& newKey, const CBORValue::MapValue& map)
{
    auto comparator = map.key_comp();
    if (!map.empty() && comparator(newKey, map.rbegin()->first)) {
        m_errorCode = DecoderError::OutOfOrderKey;
        return false;
    }
    return true;
}

CBORReader::DecoderError CBORReader::getErrorCode()
{
    return m_errorCode;
}

// static
const char* CBORReader::errorCodeToString(DecoderError error)
{
    switch (error) {
    case DecoderError::CBORNoError:
        return kNoError;
    case DecoderError::UnsupportedMajorType:
        return kUnsupportedMajorType;
    case DecoderError::UnknownAdditionalInfo:
        return kUnknownAdditionalInfo;
    case DecoderError::IncompleteCBORData:
        return kIncompleteCBORData;
    case DecoderError::IncorrectMapKeyType:
        return kIncorrectMapKeyType;
    case DecoderError::TooMuchNesting:
        return kTooMuchNesting;
    case DecoderError::InvalidUTF8:
        return kInvalidUTF8;
    case DecoderError::ExtraneousData:
        return kExtraneousData;
    case DecoderError::DuplicateKey:
        return kDuplicateKey;
    case DecoderError::OutOfOrderKey:
        return kMapKeyOutOfOrder;
    case DecoderError::NonMinimalCBOREncoding:
        return kNonMinimalCBOREncoding;
    case DecoderError::UnsupportedSimpleValue:
        return kUnsupportedSimpleValue;
    case DecoderError::UnsupportedFloatingPointValue:
        return kUnsupportedFloatingPointValue;
    case DecoderError::OutOfRangeIntegerValue:
        return kOutOfRangeIntegerValue;
    default:
        ASSERT_NOT_REACHED();
        return "Unknown error code.";
    }
}

} // namespace cbor

#endif // ENABLE(WEB_AUTHN)
