@@ -153,7 +153,6 @@ typedef struct {
153153 bool transcode_first_enter ;
154154} yajl_ctx_t ;
155155
156-
157156static inline bool
158157stack_push (yajl_ctx_t * s , char * ptr , int mask )
159158{
@@ -217,6 +216,19 @@ stack_grow(yajl_ctx_t *s, int cond)
217216#define stack_grow_array (s ) stack_grow((s), TYPE_ARRAY)
218217#define stack_grow_map (s ) stack_grow((s), TYPE_MAP)
219218
219+ static inline bool
220+ bind_data (yajl_ctx_t * s_ctx )
221+ {
222+ tp_transcode_t * tc = s_ctx -> tc ;
223+ if (tc -> data .pos && tc -> data .len ) {
224+ if (s_ctx -> tp .e - s_ctx -> tp .p < (ptrdiff_t )tc -> data .len )
225+ return false;
226+ memcpy (s_ctx -> tp .p , tc -> data .pos , tc -> data .len );
227+ tp_add (& s_ctx -> tp , tc -> data .len );
228+ }
229+ return true;
230+ }
231+
220232static int
221233yajl_null (void * ctx )
222234{
@@ -357,6 +369,7 @@ yajl_map_key(void *ctx, const unsigned char * key, size_t len)
357369 if (unlikely (s_ctx -> tc -> batch_size > MAX_BATCH_SIZE )) {
358370
359371 /* TODO '16384' -> MAX_BATCH_SIZE
372+ * Is this okay?
360373 */
361374 say_error (s_ctx , -32600 ,
362375 "too large batch, max allowed 16384 calls per request" );
@@ -366,6 +379,8 @@ yajl_map_key(void *ctx, const unsigned char * key, size_t len)
366379 if (unlikely (!tp_call_wof (& s_ctx -> tp )))
367380 say_overflow_r_2 (s_ctx );
368381
382+ /** Set method binded to this transcoding
383+ */
369384 if (!s_ctx -> read_method ) {
370385 tp_transcode_t * tc = s_ctx -> tc ;
371386 if (unlikely (!tp_call_wof_add_func (& s_ctx -> tp ,
@@ -387,7 +402,9 @@ yajl_map_key(void *ctx, const unsigned char * key, size_t len)
387402 say_overflow_r_2 (s_ctx );
388403
389404 } else if (s_ctx -> stage == WAIT_NEXT ) {
390-
405+ /**
406+ * {"params": []}
407+ */
391408 if (len == sizeof ("params" ) - 1
392409 && key [0 ] == 'p'
393410 && key [1 ] == 'a'
@@ -397,10 +414,8 @@ yajl_map_key(void *ctx, const unsigned char * key, size_t len)
397414 && key [5 ] == 's' )
398415 {
399416 dd ("PARAMS STAGE\n" );
400-
401417 if (unlikely (!tp_call_wof_add_params (& s_ctx -> tp )))
402418 say_overflow_r_2 (s_ctx );
403-
404419 s_ctx -> stage = PARAMS ;
405420 }
406421 else if (len == sizeof ("id" ) - 1
@@ -410,6 +425,9 @@ yajl_map_key(void *ctx, const unsigned char * key, size_t len)
410425 dd ("ID STAGE\n" );
411426 s_ctx -> stage = ID ;
412427 }
428+ /* {"method": STR}*
429+ *
430+ */
413431 else if (s_ctx -> read_method
414432 && len == sizeof ("method" ) - 1
415433 && key [0 ] == 'm'
@@ -444,6 +462,7 @@ yajl_start_map(void *ctx)
444462
445463 bool r = false;
446464 if (unlikely (s_ctx -> size == 0 ))
465+ /**/
447466 r = stack_push (s_ctx , s_ctx -> tp .p , TYPE_MAP | PARAMS );
448467 else
449468 r = stack_push (s_ctx , s_ctx -> tp .p , TYPE_MAP );
@@ -467,19 +486,21 @@ yajl_end_map(void *ctx)
467486{
468487 yajl_ctx_t * s_ctx = (yajl_ctx_t * )ctx ;
469488
470- /** Say we already read method. Otherwise we'll have an error.
471- * E.g. proto await for "params", "id" and "method".
472- */
473- if (!s_ctx -> read_method
474- && (s_ctx -> been_stages & (PARAMS | ID ))
475- == (PARAMS | ID ))
476- {
477- s_ctx -> been_stages |= METHOD ;
478- }
489+ if (s_ctx -> size == 0 ) {
490+
491+ if (unlikely (!tp_call_wof_add_params (& s_ctx -> tp )))
492+ say_overflow_r_2 (s_ctx );
493+
494+ if (!(s_ctx -> been_stages & PARAMS )) {
495+
496+ if (s_ctx -> tc -> data .pos && s_ctx -> tc -> data .len ) {
497+ tp_encode_array (& s_ctx -> tp , 1 );
498+ if (unlikely (!bind_data (s_ctx )))
499+ say_overflow_r_2 (s_ctx );
500+ } else
501+ tp_encode_array (& s_ctx -> tp , 0 );
502+ }
479503
480- if ((s_ctx -> been_stages & (PARAMS | ID | METHOD ))
481- == (PARAMS | ID | METHOD ))
482- {
483504 dd ("WAIT NEXT BATCH\n" );
484505 s_ctx -> stage = INIT ;
485506 s_ctx -> been_stages = 0 ;
@@ -509,12 +530,13 @@ yajl_end_map(void *ctx)
509530 return 1 ;
510531}
511532
533+
512534static int
513535yajl_start_array (void * ctx )
514536{
515537 yajl_ctx_t * s_ctx = (yajl_ctx_t * )ctx ;
516538
517- if (unlikely ( s_ctx -> stage == INIT ) ) {
539+ if (s_ctx -> stage == INIT ) {
518540 s_ctx -> batch_mode_on = true;
519541 return 1 ;
520542 }
@@ -526,33 +548,27 @@ yajl_start_array(void *ctx)
526548
527549 stack_grow_array (s_ctx );
528550
529- bool r = false, is_params = false ;
551+ bool push_ok = false, bind_first_argument = true ;
530552 if (unlikely (s_ctx -> size == 0 )) {
531- r = stack_push (s_ctx , s_ctx -> tp .p , TYPE_ARRAY | PARAMS );
532- is_params = true;
533- }
534- else
535- r = stack_push (s_ctx , s_ctx -> tp .p , TYPE_ARRAY );
553+ push_ok = stack_push (s_ctx , s_ctx -> tp .p , TYPE_ARRAY | PARAMS );
554+ bind_first_argument = true;
555+ } else
556+ push_ok = stack_push (s_ctx , s_ctx -> tp .p , TYPE_ARRAY );
536557
537- if (unlikely (!r )) {
558+ if (unlikely (!push_ok )) {
538559 say_error (s_ctx , -32603 , "[BUG?] 'stack' overflow" );
539560 return 0 ;
540561 }
541562
542- if (unlikely (s_ctx -> tp .e < s_ctx -> tp .p + 1 + sizeof (uint32_t )))
563+ if (unlikely (s_ctx -> tp .e < ( s_ctx -> tp .p + 1 + sizeof (uint32_t ) )))
543564 say_overflow_r_2 (s_ctx );
544565
545566 tp_add (& s_ctx -> tp , 1 + sizeof (uint32_t ));
546567
547- // Bind data here [
548- if (unlikely (is_params )) {
549- tp_transcode_t * tc = s_ctx -> tc ;
550- if (tc -> data .pos && tc -> data .len ) {
551- if (s_ctx -> tp .e - s_ctx -> tp .p < (ptrdiff_t )tc -> data .len )
568+ // Binding data [
569+ if (unlikely (bind_first_argument )) {
570+ if (!bind_data (s_ctx ))
552571 say_overflow_r_2 (s_ctx );
553- memcpy (s_ctx -> tp .p , tc -> data .pos , tc -> data .len );
554- tp_add (& s_ctx -> tp , tc -> data .len );
555- }
556572 }
557573 // ]
558574
@@ -705,14 +721,8 @@ yajl_json2tp_transcode(void *ctx, const char *input, size_t input_size)
705721 * So! PWN this via bool flag and some checks
706722 *
707723 * NOTE
708- * 1. Check len(buffer) is wrong.
724+ * Check len(buffer) is wrong.
709725 * We may have a very large buffer which passed to this function by 1-byte.
710- *
711- * 2. If we'll have buffer which passed to this function by 1-byte then
712- * those checks will pwn my transcoder! Wooo! Any suggestions?
713- *
714- *
715- * 3. Pwn == 'invalid json'
716726 */
717727 if (unlikely (!s_ctx -> transcode_first_enter )) {
718728 s_ctx -> transcode_first_enter = true;
@@ -758,15 +768,19 @@ yajl_json2tp_complete(void *ctx, size_t *complete_msg_size)
758768 yajl_ctx_t * s_ctx = (yajl_ctx_t * )ctx ;
759769
760770 const yajl_status stat = yajl_complete_parse (s_ctx -> hand );
771+
772+ /* OK */
761773 if (likely (stat == yajl_status_ok )) {
762774 * complete_msg_size = tp_used (& s_ctx -> tp );
763775 return TP_TRANSCODE_OK ;
764776 }
765777
778+ /* An error w/o message */
766779 if (s_ctx -> tc -> errmsg == NULL ) {
767780 say_invalid_json (s_ctx );
768781 }
769782
783+ /* ? */
770784 return TP_TRANSCODE_ERROR ;
771785}
772786
0 commit comments