Adding parsing for 128bit integers to the rai_lib interface and checking for overflows during parsing.

This commit is contained in:
clemahieu 2018-03-20 12:39:32 -05:00
commit b48ecb653c
5 changed files with 46 additions and 2 deletions

View file

@ -7,6 +7,14 @@
#include <rai/lib/numbers.hpp>
#include <rai/lib/work.hpp>
TEST (interface, xrb_uint128_to_dec)
{
rai::uint128_union zero (0);
char text[40] = { 0 };
xrb_uint128_to_dec (zero.bytes.data (), text);
ASSERT_STREQ ("0", text);
}
TEST (interface, xrb_uint256_to_string)
{
rai::uint256_union zero (0);
@ -31,6 +39,14 @@ TEST (interface, xrb_uint512_to_string)
ASSERT_STREQ ("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", text);
}
TEST (interface, xrb_uint128_from_dec)
{
rai::uint128_union zero (0);
ASSERT_EQ (0, xrb_uint128_from_dec ("340282366920938463463374607431768211455", zero.bytes.data ()));
ASSERT_EQ (1, xrb_uint128_from_dec ("340282366920938463463374607431768211456", zero.bytes.data ()));
ASSERT_EQ (1, xrb_uint128_from_dec ("3402823669209384634633%4607431768211455", zero.bytes.data ()));
}
TEST (interface, xrb_uint256_from_string)
{
rai::uint256_union zero (0);

View file

@ -37,6 +37,14 @@ TEST (uint128_union, decode_dec_leading_zero)
ASSERT_TRUE (error);
}
TEST (uint128_union, decode_dec_overflow)
{
rai::uint128_union value;
std::string text ("340282366920938463463374607431768211456");
auto error (value.decode_dec (text));
ASSERT_TRUE (error);
}
struct test_punct : std::moneypunct<char>
{
pattern do_pos_format () const

View file

@ -15,6 +15,12 @@
#include <cstring>
extern "C" {
void xrb_uint128_to_dec (xrb_uint128 source, char * destination)
{
auto const & number (*reinterpret_cast<rai::uint128_union *> (source));
strncpy (destination, number.to_string_dec ().c_str (), 32);
}
void xrb_uint256_to_string (xrb_uint256 source, char * destination)
{
auto const & number (*reinterpret_cast<rai::uint256_union *> (source));
@ -33,6 +39,13 @@ void xrb_uint512_to_string (xrb_uint512 source, char * destination)
strncpy (destination, number.to_string ().c_str (), 128);
}
int xrb_uint128_from_dec (const char * source, xrb_uint128 destination)
{
auto & number (*reinterpret_cast<rai::uint128_union *> (destination));
auto error (number.decode_dec (source));
return error ? 1 : 0;
}
int xrb_uint256_from_string (const char * source, xrb_uint256 destination)
{
auto & number (*reinterpret_cast<rai::uint256_union *> (destination));

View file

@ -5,10 +5,13 @@
extern "C" {
#endif
typedef unsigned char * xrb_uint128; // 16byte array for public and private keys
typedef unsigned char * xrb_uint256; // 32byte array for public and private keys
typedef unsigned char * xrb_uint512; // 64byte array for signatures
typedef void * xrb_transaction;
// Convert amount bytes 'source' to a 39 byte not-null-terminated decimal string 'destination'
void xrb_uint128_to_dec (const xrb_uint128 source, char * destination);
// Convert public/private key bytes 'source' to a 64 byte not-null-terminated hex string 'destination'
void xrb_uint256_to_string (const xrb_uint256 source, char * destination);
// Convert public key bytes 'source' to a 65 byte non-null-terminated account string 'destination'
@ -16,6 +19,9 @@ void xrb_uint256_to_address (xrb_uint256 source, char * destination);
// Convert public/private key bytes 'source' to a 128 byte not-null-terminated hex string 'destination'
void xrb_uint512_to_string (const xrb_uint512 source, char * destination);
// Convert 39 byte decimal string 'source' to a byte array 'destination'
// Return 0 on success, nonzero on error
int xrb_uint128_from_dec (const char * source, xrb_uint128 destination);
// Convert 64 byte hex string 'source' to a byte array 'destination'
// Return 0 on success, nonzero on error
int xrb_uint256_from_string (const char * source, xrb_uint256 destination);

View file

@ -562,11 +562,12 @@ bool rai::uint128_union::decode_dec (std::string const & text)
{
std::stringstream stream (text);
stream << std::dec << std::noshowbase;
rai::uint128_t number_l;
boost::multiprecision::checked_uint128_t number_l;
try
{
stream >> number_l;
*this = number_l;
rai::uint128_t unchecked (number_l);
*this = unchecked;
if (!stream.eof ())
{
error = true;