示例#1
0
TEST(ParseNumber, TestParsingOverflow) {
    uint64_t u64;
    // These both have one too many hex digits and will overflow the multiply. The second overflows
    // such that the truncated result is still greater than either input and can catch overly
    // simplistic overflow checks.
    ASSERT_EQUALS(ErrorCodes::FailedToParse,
                  parseNumberFromStringWithBase("0xfffffffffffffffff", 16, &u64));
    ASSERT_EQUALS(ErrorCodes::FailedToParse,
                  parseNumberFromStringWithBase("0x7ffffffffffffffff", 16, &u64));

    // 2**64 exactly. This will overflow the add.
    ASSERT_EQUALS(ErrorCodes::FailedToParse,
                  parseNumberFromStringWithBase("18446744073709551616", 10, &u64));

    uint32_t u32;
    // Too large when down-converting.
    ASSERT_EQUALS(ErrorCodes::FailedToParse,
                  parseNumberFromStringWithBase("0xfffffffff", 16, &u32));

    int32_t i32;
    // Too large when down-converting.
    ASSERT_EQUALS(
        ErrorCodes::FailedToParse,
        parseNumberFromString(std::to_string(std::numeric_limits<uint32_t>::max()), &i32));
}
示例#2
0
TEST(Double, TestRejectingBadBases) {
    double ignored;

    // Only supported base for parseNumberFromStringWithBase<double> is 0.
    ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("0", -1, &ignored));
    ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("0", 1, &ignored));
    ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("0", 8, &ignored));
    ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("0", 10, &ignored));
    ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("0", 16, &ignored));
}
示例#3
0
    Status HostAndPort::initialize(const StringData& s) {
        const size_t colonPos = s.rfind(':');
        const StringData hostPart = s.substr(0, colonPos);
        if (hostPart.empty()) {
            return Status(ErrorCodes::FailedToParse, str::stream() <<
                          "Empty host component parsing HostAndPort from \"" <<
                          escape(s.toString()) << "\"");
        }

        int port;
        if (colonPos != std::string::npos) {
            const StringData portPart = s.substr(colonPos + 1);
            Status status = parseNumberFromStringWithBase(portPart, 10, &port);
            if (!status.isOK()) {
                return status;
            }
            if (port <= 0) {
                return Status(ErrorCodes::FailedToParse, str::stream() << "Port number " << port <<
                              " out of range parsing HostAndPort from \"" << escape(s.toString()) <<
                              "\"");
            }
        }
        else {
            port = -1;
        }
        _host = hostPart.toString();
        _port = port;
        return Status::OK();
    }
示例#4
0
 static void TestRejectingBadBases() {
     NumberType ignored;
     ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("0", -1, &ignored));
     ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("10", 1, &ignored));
     ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("-10", 37, &ignored));
     ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase(" ", -1, &ignored));
     ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("f", 37, &ignored));
     ASSERT_EQUALS(ErrorCodes::BadValue, parseNumberFromStringWithBase("^%", -1, &ignored));
 }
uint64_t WiredTigerOplogManager::fetchAllCommittedValue(WT_CONNECTION* conn) {
    // Fetch the latest all_committed value from the storage engine.  This value will be a
    // timestamp that has no holes (uncommitted transactions with lower timestamps) behind it.
    char buf[(2 * 8 /*bytes in hex*/) + 1 /*nul terminator*/];
    auto wtstatus = conn->query_timestamp(conn, buf, "get=all_committed");
    if (wtstatus == WT_NOTFOUND) {
        // Treat this as lowest possible timestamp; we need to see all preexisting data but no new
        // (timestamped) data.
        return kMinimumTimestamp;
    } else {
        invariantWTOK(wtstatus);
    }

    uint64_t tmp;
    fassert(38002, parseNumberFromStringWithBase(buf, 16, &tmp));
    return tmp;
}
Timestamp WiredTigerRecoveryUnit::_beginTransactionAtAllCommittedTimestamp(WT_SESSION* session) {
    WiredTigerBeginTxnBlock txnOpen(session, _ignorePrepared);
    Timestamp txnTimestamp = Timestamp(_oplogManager->fetchAllCommittedValue(session->connection));
    auto status =
        txnOpen.setTimestamp(txnTimestamp, WiredTigerBeginTxnBlock::RoundToOldest::kRound);
    fassert(50948, status);

    // Since this is not in a critical section, we might have rounded to oldest between
    // calling getAllCommitted and setTimestamp.  We need to get the actual read timestamp we
    // used.
    char buf[(2 * 8 /*bytes in hex*/) + 1 /*nul terminator*/];
    auto wtstatus = session->query_timestamp(session, buf, "get=read");
    invariantWTOK(wtstatus);
    uint64_t read_timestamp;
    fassert(50949, parseNumberFromStringWithBase(buf, 16, &read_timestamp));
    txnOpen.done();
    return Timestamp(read_timestamp);
}
    /**
     * Parse server-first-message on the form:
     * r=client-nonce|server-nonce,s=user-salt,i=iteration-count
     *
     * Generate client-final-message of the form:
     * c=channel-binding(base64),r=client-nonce|server-nonce,p=ClientProof
     *
     **/
    StatusWith<bool> SaslSCRAMSHA1ClientConversation::_secondStep(const std::vector<std::string>& input,
                                                                  std::string* outputData) {
        if (input.size() != 3) {
            return StatusWith<bool>(ErrorCodes::BadValue, mongoutils::str::stream() <<
                "Incorrect number of arguments for first SCRAM-SHA-1 server message, got " <<
                input.size() << " expected 3");
        }
        else if (!str::startsWith(input[0], "r=") || input[0].size() < 2) {
            return StatusWith<bool>(ErrorCodes::BadValue, mongoutils::str::stream() <<
                "Incorrect SCRAM-SHA-1 client|server nonce: " << input[0]);
        }
        else if (!str::startsWith(input[1], "s=") || input[1].size() < 6) {
            return StatusWith<bool>(ErrorCodes::BadValue, mongoutils::str::stream() <<
                "Incorrect SCRAM-SHA-1 salt: " << input[1]);
        }
        else if(!str::startsWith(input[2], "i=") || input[2].size() < 3) {
            return StatusWith<bool>(ErrorCodes::BadValue, mongoutils::str::stream() <<
                "Incorrect SCRAM-SHA-1 iteration count: " << input[2]);
        }

        std::string nonce = input[0].substr(2);
        if(!str::startsWith(nonce, _clientNonce)) {
            return StatusWith<bool>(ErrorCodes::BadValue, mongoutils::str::stream() <<
                "Server SCRAM-SHA-1 nonce does not match client nonce" << input[2]);
        }

        std::string salt = input[1].substr(2);
        int iterationCount;

        Status status = parseNumberFromStringWithBase(input[2].substr(2), 10, &iterationCount);
        if (status != Status::OK()) {
            return StatusWith<bool>(ErrorCodes::BadValue, mongoutils::str::stream() <<
                "Failed to parse SCRAM-SHA-1 iteration count: " << input[2]);
        }

        // Append client-final-message-without-proof to _authMessage
        _authMessage += "c=biws,r=" + nonce;

        std::string decodedSalt;
        try {
            decodedSalt = base64::decode(salt);
        }
        catch (const DBException& ex) {
            return StatusWith<bool>(ex.toStatus());
        }

        scram::generateSaltedPassword(
                            _saslClientSession->getParameter(SaslClientSession::parameterPassword),
                            reinterpret_cast<const unsigned char*>(decodedSalt.c_str()),
                            decodedSalt.size(),
                            iterationCount,
                            _saltedPassword);

        std::string clientProof = scram::generateClientProof(_saltedPassword, _authMessage);

        StringBuilder sb;
        sb << "c=biws,r=" << nonce << ",p=" << clientProof;
        *outputData = sb.str();

        return StatusWith<bool>(false);
    }
示例#8
0
    Status HostAndPort::initialize(const StringData& s) {
        size_t colonPos = s.rfind(':');
        StringData hostPart = s.substr(0, colonPos);

        // handle ipv6 hostPart (which we require to be wrapped in []s)
        const size_t openBracketPos = s.find('[');
        const size_t closeBracketPos = s.find(']');
        if (openBracketPos != std::string::npos) {
            if (openBracketPos != 0) {
                return Status(ErrorCodes::FailedToParse,
                              str::stream() << "'[' present, but not first character in "
                                            << s.toString());
            }
            if (closeBracketPos == std::string::npos) {
                return Status(ErrorCodes::FailedToParse,
                              str::stream() << "ipv6 address is missing closing ']' in hostname in "
                                            << s.toString());
            }

            hostPart = s.substr(openBracketPos+1, closeBracketPos-openBracketPos-1);
            // prevent accidental assignment of port to the value of the final portion of hostPart
            if (colonPos < closeBracketPos) {
                colonPos = std::string::npos;
            }
            else if (colonPos != closeBracketPos+1) {
                return Status(ErrorCodes::FailedToParse,
                              str::stream() << "Extraneous characters between ']' and pre-port ':'"
                                            << " in " << s.toString());
            }
        }
        else if (closeBracketPos != std::string::npos) {
            return Status(ErrorCodes::FailedToParse,
                          str::stream() << "']' present without '[' in " << s.toString());
        }

        if (hostPart.empty()) {
            return Status(ErrorCodes::FailedToParse, str::stream() <<
                          "Empty host component parsing HostAndPort from \"" <<
                          escape(s.toString()) << "\"");
        }

        int port;
        if (colonPos != std::string::npos) {
            const StringData portPart = s.substr(colonPos + 1);
            Status status = parseNumberFromStringWithBase(portPart, 10, &port);
            if (!status.isOK()) {
                return status;
            }
            if (port <= 0) {
                return Status(ErrorCodes::FailedToParse, str::stream() << "Port number " << port <<
                              " out of range parsing HostAndPort from \"" << escape(s.toString()) <<
                              "\"");
            }
        }
        else {
            port = -1;
        }
        _host = hostPart.toString();
        _port = port;
        return Status::OK();
    }
示例#9
0
 static void TestParsingWithExplicitBase() {
     NumberType x;
     ASSERT_PARSES_WITH_BASE(NumberType, "15b", 16, 0x15b);
     ASSERT_PARSES_WITH_BASE(NumberType, "77", 8, 077);
     ASSERT_PARSES_WITH_BASE(NumberType, "z", 36, 35);
     ASSERT_PARSES_WITH_BASE(NumberType, "09", 10, 9);
     ASSERT_PARSES_WITH_BASE(NumberType, "00000000000z0", 36, 35 * 36);
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("1b", 10, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("80", 8, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("0X", 16, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("0x", 16, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("0x", 8, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("0X", 8, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("0x", 10, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("0X", 10, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("+0X", 16, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("+0x", 16, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("+0x", 8, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("+0X", 8, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("+0x", 10, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("+0X", 10, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("-0X", 16, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("-0x", 16, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("-0x", 8, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("-0X", 8, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("-0x", 10, &x));
     ASSERT_EQUALS(ErrorCodes::FailedToParse, parseNumberFromStringWithBase("-0X", 10, &x));
 }