@@ -875,6 +875,22 @@ static void json_append_tagged_quaternion(strbuf_t *json, const float *a, bool t
875875 strbuf_append_string (json, tight ? " \" " : " >\" " );
876876}
877877
878+ static void json_append_buffer (lua_State *l, strbuf_t *json, int lindex)
879+ {
880+ size_t buf_len = 0 ;
881+ void *data = luaL_checkbuffer (l, lindex, &buf_len);
882+
883+ // Need to use something that will automatically de-alloc in case we hit
884+ // a memory limit appending to the buffer.
885+ std::vector<char > encode_buf ((size_t )apr_base64_encode_len (buf_len));
886+ size_t encoded_len = apr_base64_encode_binary (encode_buf.data (), (const uint8_t *)data, buf_len);
887+ if (encoded_len > 0 )
888+ {
889+ // exclude the trailing null
890+ strbuf_append_mem (json, encode_buf.data (), encoded_len - 1 );
891+ }
892+ }
893+
878894// Helper to parse a hex character to its value (returns -1 on error)
879895static inline int hex_char_to_int (char c) {
880896 if (c >= ' 0' && c <= ' 9' ) return c - ' 0' ;
@@ -1025,10 +1041,16 @@ static void json_append_object(lua_State *l, json_config_t *cfg,
10251041 json_append_tagged_float (json, lua_tonumber (l, -2 ), cfg->encode_number_precision );
10261042 break ;
10271043 case LUA_TVECTOR: {
1028- const float * a = lua_tovector (l, -2 );
1044+ const float * a = lua_tovector (l, -2 );
10291045 json_append_tagged_vector (json, a, cfg->sl_tight_encoding );
10301046 break ;
10311047 }
1048+ case LUA_TBUFFER: {
1049+ strbuf_append_string (json, " \" !d" );
1050+ json_append_buffer (l, json, -2 );
1051+ strbuf_append_char (json, ' "' );
1052+ break ;
1053+ }
10321054 case LUA_TUSERDATA: {
10331055 int tag = lua_userdatatag (l, -2 );
10341056 if (tag == UTAG_UUID) {
@@ -1220,18 +1242,10 @@ static int json_append_data(lua_State *l, json_config_t *cfg,
12201242 }
12211243 case LUA_TBUFFER: {
12221244 strbuf_append_char (json, ' "' );
1223- size_t buf_len = 0 ;
1224- void *data = luaL_checkbuffer (l, -1 , &buf_len);
1225-
1226- // Need to use something that will automatically de-alloc in case we hit
1227- // a memory limit appending to the buffer.
1228- std::vector<char > encode_buf ((size_t )apr_base64_encode_len (buf_len));
1229- size_t encoded_len = apr_base64_encode_binary (encode_buf.data (), (const uint8_t *)data, buf_len);
1230- if (encoded_len > 0 )
1231- {
1232- // exclude the trailing null
1233- strbuf_append_mem (json, encode_buf.data (), encoded_len - 1 );
1234- }
1245+ if (cfg->sl_tagged_types )
1246+ strbuf_append_string (json, " !d" );
1247+
1248+ json_append_buffer (l, json, -1 );
12351249 strbuf_append_char (json, ' "' );
12361250 break ;
12371251 }
@@ -1535,6 +1549,25 @@ static bool json_parse_tagged_string(lua_State *l, const char *str, size_t len)
15351549 luaL_error (l, " malformed tagged boolean: %s" , str);
15361550 return false ;
15371551
1552+ case ' d' :
1553+ {
1554+ // Buffer (data): !d<base64 data>
1555+
1556+ if (payload_len > 0 )
1557+ {
1558+ std::vector<uint8_t > decode_buf (payload_len);
1559+ size_t new_len = apr_base64_decode_binary (decode_buf.data (), payload);
1560+ if (new_len > 0 )
1561+ {
1562+ void * buf_data = lua_newbuffer (l, new_len);
1563+ memcpy (buf_data, decode_buf.data (), new_len);
1564+ return true ;
1565+ }
1566+ }
1567+ lua_newbuffer (l, 0 );
1568+ return true ;
1569+ }
1570+
15381571 default :
15391572 luaL_error (l, " unknown tag '!%c' in string: %s" , tag, str);
15401573 return false ; // unreachable
0 commit comments