Skip to content

Commit

Permalink
#1702 improve input proccessing for precompileds
Browse files Browse the repository at this point in the history
  • Loading branch information
olehnikolaiev committed Nov 13, 2023
1 parent ea694fc commit ca16ebf
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 13 deletions.
14 changes: 9 additions & 5 deletions libethereum/Precompiled.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,16 @@ static Logger& getLogger( int a_severity = VerbosityTrace ) {

static void convertBytesToString(
bytesConstRef _in, size_t _startPosition, std::string& _out, size_t& _stringLength ) {
if ( _in.size() < UINT256_SIZE ) {
throw std::runtime_error( "Input is too short - invalid input in convertBytesToString()" );
}
bigint const sstringLength( parseBigEndianRightPadded( _in, _startPosition, UINT256_SIZE ) );
_stringLength = sstringLength.convert_to< size_t >();
if ( _startPosition + UINT256_SIZE + _stringLength > _in.size() ) {
throw std::runtime_error( "Invalid input in convertBytesToString()" );
}
vector_ref< const unsigned char > byteFilename =
_in.cropped( _startPosition + 32, _stringLength );
_in.cropped( _startPosition + UINT256_SIZE, _stringLength );
_out = std::string( ( char* ) byteFilename.data(), _stringLength );
}

Expand Down Expand Up @@ -753,7 +759,6 @@ static std::pair< std::string, unsigned > parseHistoricFieldRequest( std::string
// first 3 elements are skaleConfig, sChain, nodes - it was checked before
unsigned id = std::stoul( splitted.at( 3 ) );
std::string fieldName;
boost::trim_if( splitted.at( 4 ), []( char c ) { return c == '\0'; } );
std::set< std::string > allowedValues{ "id", "schainIndex", "owner" };
fieldName = splitted.at( 4 );
if ( allowedValues.count( fieldName ) ) {
Expand Down Expand Up @@ -782,7 +787,7 @@ static std::pair< std::string, unsigned > parseHistoricFieldRequest( std::string
* to request the value for 1-st node (1 based) for the node id field the input should be
* input=skaleConfig.sChain.nodes.0.id (inside skaled node indexes are 0 based)
* so one should pass the following as calldata:
* toBytes( ( ( input.length + 1 ) / 32 ) * 32) + toBytes(input)
* toBytes( input.length + toBytes(input) )
*/
ETH_REGISTER_PRECOMPILED( getConfigVariableUint256 )( bytesConstRef _in ) {
try {
Expand Down Expand Up @@ -855,8 +860,7 @@ ETH_REGISTER_PRECOMPILED( getConfigVariableUint256 )( bytesConstRef _in ) {
* to request the value for 2-nd node (1 based) for the owner field the input should be
* input=skaleConfig.sChain.nodes.1.owner (inside skaled node indexes are 0 based)
* so one should pass the following as calldata
* toBytes( ( ( input.length + 1 ) / 32 ) * 32) + toBytes(input)
*
* toBytes( input.length + toBytes(input) )
*/
ETH_REGISTER_PRECOMPILED( getConfigVariableAddress )( bytesConstRef _in ) {
try {
Expand Down
31 changes: 23 additions & 8 deletions test/unittests/libethereum/PrecompiledTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1715,25 +1715,32 @@ BOOST_AUTO_TEST_CASE( getConfigVariableUint256 ) {
dev::eth::g_skaleHost = testClient->skaleHost();

PrecompiledExecutor exec = PrecompiledRegistrar::executor( "getConfigVariableUint256" );
std::string input = stringToHex( "skaleConfig.sChain.nodes.0.id" );
input = input.substr(0, 58); // remove 0s in the end

bytes in = fromHex( numberToHex( 32 ) + stringToHex( "skaleConfig.sChain.nodes.0.id" ) );
bytes in = fromHex( numberToHex( 29 ) + input );
auto res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( res.first );
BOOST_REQUIRE( dev::fromBigEndian<dev::u256>( res.second ) == 30 );

in = fromHex( numberToHex( 64 ) + stringToHex( "skaleConfig.sChain.nodes.0.schainIndex" ) );
input = stringToHex( "skaleConfig.sChain.nodes.0.schainIndex" );
input = input.substr(0, 76); // remove 0s in the end
in = fromHex( numberToHex( 38 ) + input );
res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( res.first );
BOOST_REQUIRE( dev::fromBigEndian<dev::u256>( res.second ) == 13 );

in = fromHex( numberToHex( 32 ) + stringToHex( "skaleConfig.sChain.nodes.0.owner" ) );
input = stringToHex( "skaleConfig.sChain.nodes.0.owner" );
in = fromHex( numberToHex( 32 ) + input );
res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( !res.first );

in = fromHex( numberToHex( 64 ) + stringToHex( "skaleConfig.sChain.nodes.0.unknownField" ) );
input = stringToHex( "skaleConfig.sChain.nodes.0.unknownField" );
input = input.substr(0, 78); // remove 0s in the end
in = fromHex( numberToHex( 39 ) + input );
res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( !res.first );
Expand Down Expand Up @@ -1767,23 +1774,31 @@ BOOST_AUTO_TEST_CASE( getConfigVariableAddress ) {

PrecompiledExecutor exec = PrecompiledRegistrar::executor( "getConfigVariableAddress" );

bytes in = fromHex( numberToHex( 32 ) + stringToHex( "skaleConfig.sChain.nodes.0.owner" ) );
std::string input = stringToHex( "skaleConfig.sChain.nodes.0.owner" );
bytes in = fromHex( numberToHex( 32 ) + input );
auto res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( res.first );
BOOST_REQUIRE( res.second == fromHex("0x23bbe8db4e347b4e8c937c1c8350e4b5ed33adb3db69cbdb7a38e1f40a1b82fe") );

in = fromHex( numberToHex( 32 ) + stringToHex( "skaleConfig.sChain.nodes.0.id" ) );
input = stringToHex( "skaleConfig.sChain.nodes.0.id" );
input = input.substr(0, 58); // remove 0s in the end

in = fromHex( numberToHex( 29 ) + input );
res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( !res.first );

in = fromHex( numberToHex( 64 ) + stringToHex( "skaleConfig.sChain.nodes.0.schainIndex" ) );
input = stringToHex( "skaleConfig.sChain.nodes.0.schainIndex" );
input = input.substr(0, 76); // remove 0s in the end
in = fromHex( numberToHex( 38 ) + input );
res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( !res.first );

in = fromHex( numberToHex( 64 ) + stringToHex( "skaleConfig.sChain.nodes.0.unknownField" ) );
input = stringToHex( "skaleConfig.sChain.nodes.0.unknownField" );
input = input.substr(0, 78); // remove 0s in the end
in = fromHex( numberToHex( 39 ) + input );
res = exec( bytesConstRef( in.data(), in.size() ) );

BOOST_REQUIRE( !res.first );
Expand Down

0 comments on commit ca16ebf

Please sign in to comment.