From b8a7531eab08af3756eb4670437484ae2e137d74 Mon Sep 17 00:00:00 2001 From: Eric Frias Date: Tue, 6 May 2014 17:20:04 -0400 Subject: [PATCH 1/2] Fix error message printed when unable to deserialize a json object, improve logging of return values and add logging of exceptional returns from json function calls. Continue my endless quest to break the mac build. --- include/fc/io/datastream.hpp | 2 +- src/io/datastream.cpp | 2 +- src/network/tcp_socket.cpp | 8 ++++---- src/rpc/json_connection.cpp | 4 +++- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/include/fc/io/datastream.hpp b/include/fc/io/datastream.hpp index 5e54998..75a4269 100644 --- a/include/fc/io/datastream.hpp +++ b/include/fc/io/datastream.hpp @@ -7,7 +7,7 @@ namespace fc { namespace detail { - NO_RETURN void throw_datastream_range_error( const char* file, size_t len, size_t over ); + NO_RETURN void throw_datastream_range_error( const char* file, size_t len, int64_t over ); } /** diff --git a/src/io/datastream.cpp b/src/io/datastream.cpp index da38e14..cfe1104 100644 --- a/src/io/datastream.cpp +++ b/src/io/datastream.cpp @@ -1,7 +1,7 @@ #include #include -NO_RETURN void fc::detail::throw_datastream_range_error(char const* method, size_t len, size_t over) +NO_RETURN void fc::detail::throw_datastream_range_error(char const* method, size_t len, int64_t over) { FC_THROW_EXCEPTION( out_of_range_exception, "${method} datastream of length ${len} over by ${over}", ("method",fc::string(method))("len",len)("over",over) ); } diff --git a/src/network/tcp_socket.cpp b/src/network/tcp_socket.cpp index b6e807a..b9fdab7 100644 --- a/src/network/tcp_socket.cpp +++ b/src/network/tcp_socket.cpp @@ -110,19 +110,19 @@ namespace fc { // This should work for modern Linuxes and for OSX >= Mountain Lion int timeout_sec = interval.count() / fc::seconds(1).count(); if (setsockopt(my->_sock.native(), IPPROTO_TCP, - #if defined( __APPLE__ ) + #if defined( __APPLE__ ) TCP_KEEPALIVE, #else TCP_KEEPIDLE, #endif (char*)&timeout_sec, sizeof(timeout_sec)) < 0) wlog("Error setting TCP keepalive idle time"); - #ifndef __APPLE__ // TCP_KEEPINTVL does not seem to work on 10.8.4 +# if !defined(__APPLE__) || defined(TCP_KEEPINTVL) // TCP_KEEPINTVL not defined before 10.9 if (setsockopt(my->_sock.native(), IPPROTO_TCP, TCP_KEEPINTVL, (char*)&timeout_sec, sizeof(timeout_sec)) < 0) wlog("Error setting TCP keepalive interval"); - #endif // !__APPLE__ -#endif +# endif // !__APPLE__ || TCP_KEEPINTVL +#endif // !WIN32 } else { diff --git a/src/rpc/json_connection.cpp b/src/rpc/json_connection.cpp index ffd05f2..4a112b4 100644 --- a/src/rpc/json_connection.cpp +++ b/src/rpc/json_connection.cpp @@ -35,7 +35,7 @@ namespace fc { namespace rpc { void send_result( variant id, variant result ) { - ilog( "send ${i} ${r}", ("i",id)("r",result) ); + ilog( "send: {\"id\": ${i}, \"result\": ${r}}", ("i",id)("r",result) ); { fc::scoped_lock lock(_write_mutex); *_out << "{\"id\":"; @@ -48,6 +48,8 @@ namespace fc { namespace rpc { } void send_error( variant id, fc::exception& e ) { + ilog( "send: {\"id\": ${i}, \"error\":{\"message\": ${what},\"code\":0,\"data\":${data}}}", + ("i",id)("what",e.what())("data", e) ); { fc::scoped_lock lock(_write_mutex); *_out << "{\"id\":"; From 3a34299199bf56aec4077392d7e10d1189ae3a0f Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 7 May 2014 21:27:37 -0400 Subject: [PATCH 2/2] update json validation and varint hashing --- include/fc/io/enum_type.hpp | 2 +- include/fc/io/json.hpp | 2 ++ include/fc/io/varint.hpp | 18 ++++++++++++++++-- include/fc/reflect/typename.hpp | 5 +++++ src/io/json.cpp | 10 ++++++++++ 5 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/fc/io/enum_type.hpp b/include/fc/io/enum_type.hpp index 2127ac2..0406976 100644 --- a/include/fc/io/enum_type.hpp +++ b/include/fc/io/enum_type.hpp @@ -50,7 +50,7 @@ namespace fc template void to_variant( const enum_type& var, variant& vo ) { - vo = var.value; + vo = (EnumType)var.value; } template void from_variant( const variant& var, enum_type& vo ) diff --git a/include/fc/io/json.hpp b/include/fc/io/json.hpp index eada29a..4931f9b 100644 --- a/include/fc/io/json.hpp +++ b/include/fc/io/json.hpp @@ -26,6 +26,8 @@ namespace fc static string to_string( const variant& v ); static string to_pretty_string( const variant& v ); + static bool is_valid( const std::string& json_str ); + template static void save_to_file( const T& v, const fc::path& fi, bool pretty = true ) { diff --git a/include/fc/io/varint.hpp b/include/fc/io/varint.hpp index c292bcc..ad4ac21 100644 --- a/include/fc/io/varint.hpp +++ b/include/fc/io/varint.hpp @@ -33,10 +33,12 @@ struct unsigned_int { * Uses the google protobuf algorithm for seralizing signed numbers */ struct signed_int { - signed_int( int32_t v = 0 ):value(v){} + signed_int( int64_t v = 0 ):value(v){} operator int32_t()const { return value; } template signed_int& operator=( const T& v ) { value = v; return *this; } + signed_int& operator++(int){ ++value; return *this; } + signed_int& operator++(){ ++value; return *this; } int32_t value; }; @@ -50,4 +52,16 @@ void from_variant( const variant& var, unsigned_int& vo ); } // namespace fc - +#include +namespace std +{ + template<> + struct hash + { + public: + size_t operator()(const fc::signed_int &a) const + { + return std::hash()(a.value); + } + }; +} diff --git a/include/fc/reflect/typename.hpp b/include/fc/reflect/typename.hpp index 20cd1f6..9329023 100644 --- a/include/fc/reflect/typename.hpp +++ b/include/fc/reflect/typename.hpp @@ -21,4 +21,9 @@ namespace fc { template<> struct get_typename { static const char* name() { return "value"; } }; template<> struct get_typename> { static const char* name() { return "std::vector"; } }; + struct signed_int; + struct unsigned_int; + template<> struct get_typename { static const char* name() { return "signed_int"; } }; + template<> struct get_typename { static const char* name() { return "unsigned_int"; } }; + } diff --git a/src/io/json.cpp b/src/io/json.cpp index a746ddf..54b63f3 100644 --- a/src/io/json.cpp +++ b/src/io/json.cpp @@ -640,4 +640,14 @@ namespace fc return out; } + bool json::is_valid( const std::string& utf8_str ) + { + if( utf8_str.size() == 0 ) return false; + fc::stringstream in( utf8_str ); + variant_from_stream( in ); + try { in.peek(); } catch ( const eof_exception& e ) { return true; } + return false; + } + + } // fc