@@ -634,6 +634,154 @@ void test_json_pack_bug1278()
634634 }
635635}
636636
637+ static int check_msgpack_val (msgpack_object obj , int expected_type , char * expected_val )
638+ {
639+ int len ;
640+
641+ if (!TEST_CHECK (obj .type == expected_type )) {
642+ TEST_MSG ("type mismatch\nexpected=%d got=%d" , expected_type , obj .type );
643+ return -1 ;
644+ }
645+ switch (obj .type ) {
646+ case MSGPACK_OBJECT_MAP :
647+ if (!TEST_CHECK (obj .via .map .size == atoi (expected_val ))) {
648+ TEST_MSG ("map size mismatch\nexpected=%s got=%d" , expected_val , obj .via .map .size );
649+ return -1 ;
650+ }
651+ break ;
652+
653+ case MSGPACK_OBJECT_ARRAY :
654+ if (!TEST_CHECK (obj .via .array .size == atoi (expected_val ))) {
655+ TEST_MSG ("array size mismatch\nexpected=%s got=%d" , expected_val , obj .via .array .size );
656+ return -1 ;
657+ }
658+ break ;
659+
660+ case MSGPACK_OBJECT_STR :
661+ len = strlen (expected_val );
662+ if (!TEST_CHECK (obj .via .str .size == strlen (expected_val ))) {
663+ TEST_MSG ("str size mismatch\nexpected=%d got=%d" , len , obj .via .str .size );
664+ return -1 ;
665+ }
666+ else if (!TEST_CHECK (strncmp (expected_val , obj .via .str .ptr ,len ) == 0 )) {
667+ TEST_MSG ("str mismatch\nexpected=%.*s got=%.*s" , len , expected_val , len , obj .via .str .ptr );
668+ return -1 ;
669+ }
670+ break ;
671+
672+ case MSGPACK_OBJECT_POSITIVE_INTEGER :
673+ if (!TEST_CHECK (obj .via .u64 == (uint64_t )atoi (expected_val ))) {
674+ TEST_MSG ("int mismatch\nexpected=%s got=%" PRIu64 , expected_val , obj .via .u64 );
675+ return -1 ;
676+ }
677+ break ;
678+
679+ case MSGPACK_OBJECT_BOOLEAN :
680+ if (obj .via .boolean ) {
681+ if (!TEST_CHECK (strncasecmp (expected_val , "true" ,4 ) == 0 )) {
682+ TEST_MSG ("bool mismatch\nexpected=%s got=true" , expected_val );
683+ return -1 ;
684+ }
685+ }
686+ else {
687+ if (!TEST_CHECK (strncasecmp (expected_val , "false" ,5 ) == 0 )) {
688+ TEST_MSG ("bool mismatch\nexpected=%s got=false" , expected_val );
689+ return -1 ;
690+ }
691+ }
692+ break ;
693+
694+ default :
695+ TEST_MSG ("unknown type %d" , obj .type );
696+ return -1 ;
697+ }
698+
699+ return 0 ;
700+ }
701+
702+ /*
703+ * https://github.com/fluent/fluent-bit/issues/5336
704+ * Pack "valid JSON + partial JSON"
705+ */
706+ #define JSON_BUG5336 "{\"int\":10, \"string\":\"hello\", \"bool\":true, \"array\":[0,1,2]}"
707+ void test_json_pack_bug5336 ()
708+ {
709+ int ret ;
710+ char * json_valid = JSON_BUG5336 ;
711+ size_t len = strlen (json_valid );
712+
713+ char * json_incomplete = JSON_BUG5336 JSON_BUG5336 ;
714+ char * out = NULL ;
715+ int out_size ;
716+ struct flb_pack_state state ;
717+ int i ;
718+
719+ msgpack_unpacked result ;
720+ msgpack_object obj ;
721+ size_t off = 0 ;
722+
723+ int loop_cnt = 0 ;
724+
725+ for (i = len ; i < len * 2 ; i ++ ) {
726+ loop_cnt ++ ;
727+
728+ flb_pack_state_init (& state );
729+
730+ /* Pass small string size to create incomplete JSON */
731+ ret = flb_pack_json_state (json_incomplete , i , & out , & out_size , & state );
732+ if (!TEST_CHECK (ret != FLB_ERR_JSON_INVAL )) {
733+ TEST_MSG ("%ld: FLB_ERR_JSON_INVAL\njson=%.*s" , i - len , i , json_incomplete );
734+ exit (EXIT_FAILURE );
735+ }
736+ else if (!TEST_CHECK (ret != FLB_ERR_JSON_PART )) {
737+ TEST_MSG ("%ld: FLB_ERR_JSON_PART\njson=%.*s" , i - len , i , json_incomplete );
738+ exit (EXIT_FAILURE );
739+ }
740+
741+ /* unpack parsed data */
742+ msgpack_unpacked_init (& result );
743+ off = 0 ;
744+ TEST_CHECK (msgpack_unpack_next (& result , out , out_size , & off ) == MSGPACK_UNPACK_SUCCESS );
745+
746+ TEST_CHECK (check_msgpack_val (result .data , MSGPACK_OBJECT_MAP , "4" /*map size*/ ) == 0 );
747+
748+ /* "int":10 */
749+ obj = result .data .via .map .ptr [0 ].key ;
750+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_STR , "int" ) == 0 );
751+ obj = result .data .via .map .ptr [0 ].val ;
752+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_POSITIVE_INTEGER , "10" ) == 0 );
753+
754+ /* "string":"hello"*/
755+ obj = result .data .via .map .ptr [1 ].key ;
756+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_STR , "string" ) == 0 );
757+ obj = result .data .via .map .ptr [1 ].val ;
758+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_STR , "hello" ) == 0 );
759+
760+ /* "bool":true */
761+ obj = result .data .via .map .ptr [2 ].key ;
762+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_STR , "bool" ) == 0 );
763+ obj = result .data .via .map .ptr [2 ].val ;
764+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_BOOLEAN , "true" ) == 0 );
765+
766+ /* "array":[0,1,2] */
767+ obj = result .data .via .map .ptr [3 ].key ;
768+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_STR , "array" ) == 0 );
769+ obj = result .data .via .map .ptr [3 ].val ;
770+ TEST_CHECK (check_msgpack_val (obj , MSGPACK_OBJECT_ARRAY , "3" /*array size*/ ) == 0 );
771+ TEST_CHECK (check_msgpack_val (obj .via .array .ptr [0 ], MSGPACK_OBJECT_POSITIVE_INTEGER , "0" ) == 0 );
772+ TEST_CHECK (check_msgpack_val (obj .via .array .ptr [1 ], MSGPACK_OBJECT_POSITIVE_INTEGER , "1" ) == 0 );
773+ TEST_CHECK (check_msgpack_val (obj .via .array .ptr [2 ], MSGPACK_OBJECT_POSITIVE_INTEGER , "2" ) == 0 );
774+
775+ msgpack_unpacked_destroy (& result );
776+ flb_free (out );
777+ flb_pack_state_reset (& state );
778+ }
779+
780+ if (!TEST_CHECK (loop_cnt == len )) {
781+ TEST_MSG ("loop_cnt expect=%ld got=%d" , len , loop_cnt );
782+ }
783+ }
784+
637785TEST_LIST = {
638786 /* JSON maps iteration */
639787 { "json_pack" , test_json_pack },
@@ -644,6 +792,7 @@ TEST_LIST = {
644792 { "json_dup_keys" , test_json_dup_keys },
645793 { "json_pack_bug342" , test_json_pack_bug342 },
646794 { "json_pack_bug1278" , test_json_pack_bug1278 },
795+ { "json_pack_bug5336" , test_json_pack_bug5336 },
647796
648797 /* Mixed bytes, check JSON encoding */
649798 { "utf8_to_json" , test_utf8_to_json },
0 commit comments