@@ -331,10 +331,6 @@ int jwt_verify_body(char *body, zval *return_value)
331331 time_t curr_time = time ((time_t * )NULL );
332332 zend_string * vs = jwt_b64_url_decode (body );
333333
334- /* decode json to array */
335- php_json_decode_ex (return_value , ZSTR_VAL (vs ), ZSTR_LEN (vs ), PHP_JSON_OBJECT_AS_ARRAY , 512 );
336- zend_string_free (vs );
337-
338334#define FORMAT_CEX_TIME (t , cex ) do { \
339335 struct tm *timeinfo; \
340336 char buf[128]; \
@@ -349,55 +345,65 @@ int jwt_verify_body(char *body, zval *return_value)
349345 err_msg = msg; \
350346 } while(0);
351347
352- /* set expiration and not before */
353- JWT_G (expiration ) = jwt_hash_str_find_long (return_value , "exp" );
354- JWT_G (not_before ) = jwt_hash_str_find_long (return_value , "nbf" );
355- JWT_G (iat ) = jwt_hash_str_find_long (return_value , "iat" );
356-
357- /* expiration */
358- if (JWT_G (expiration ) && (curr_time - JWT_G (leeway )) >= JWT_G (expiration ))
359- FORMAT_CEX_MSG ("Expired token" , jwt_expired_signature_cex );
360-
361- /* not before */
362- if (JWT_G (not_before ) && JWT_G (not_before ) > (curr_time + JWT_G (leeway )))
363- FORMAT_CEX_TIME (JWT_G (not_before ), jwt_before_valid_cex );
364-
365- /* iat */
366- if (JWT_G (iat ) && JWT_G (iat ) > (curr_time + JWT_G (leeway )))
367- FORMAT_CEX_TIME (JWT_G (iat ), jwt_invalid_iat_cex );
368-
369- /* iss */
370- if (jwt_verify_claims_str (return_value , "iss" , JWT_G (iss )))
371- FORMAT_CEX_MSG ("Invalid Issuer" , jwt_invalid_issuer_cex );
348+ if (!vs ) {
349+ FORMAT_CEX_MSG ("Invalid body" , spl_ce_UnexpectedValueException );
350+ goto done ;
351+ }
372352
373- /* jti */
374- if ( jwt_verify_claims_str ( return_value , "jti" , JWT_G ( jti )))
375- FORMAT_CEX_MSG ( "Invalid Jti" , jwt_invalid_jti_cex );
353+ /* decode json to array */
354+ php_json_decode_ex ( return_value , ZSTR_VAL ( vs ), ZSTR_LEN ( vs ), PHP_JSON_OBJECT_AS_ARRAY , 512 );
355+ zend_string_free ( vs );
376356
377- /* aud */
378- size_t flag = 0 ;
379- zval * zv_aud = zend_hash_str_find (Z_ARRVAL_P (return_value ), "aud" , strlen ("aud" ));
357+ if (Z_TYPE (* return_value ) == IS_ARRAY ) {
358+ /* set expiration and not before */
359+ JWT_G (expiration ) = jwt_hash_str_find_long (return_value , "exp" );
360+ JWT_G (not_before ) = jwt_hash_str_find_long (return_value , "nbf" );
361+ JWT_G (iat ) = jwt_hash_str_find_long (return_value , "iat" );
362+
363+ /* expiration */
364+ if (JWT_G (expiration ) && (curr_time - JWT_G (leeway )) >= JWT_G (expiration ))
365+ FORMAT_CEX_MSG ("Expired token" , jwt_expired_signature_cex );
366+ /* not before */
367+ if (JWT_G (not_before ) && JWT_G (not_before ) > (curr_time + JWT_G (leeway )))
368+ FORMAT_CEX_TIME (JWT_G (not_before ), jwt_before_valid_cex );
369+ /* iat */
370+ if (JWT_G (iat ) && JWT_G (iat ) > (curr_time + JWT_G (leeway )))
371+ FORMAT_CEX_TIME (JWT_G (iat ), jwt_invalid_iat_cex );
372+ /* iss */
373+ if (jwt_verify_claims_str (return_value , "iss" , JWT_G (iss )))
374+ FORMAT_CEX_MSG ("Invalid Issuer" , jwt_invalid_issuer_cex );
375+ /* jti */
376+ if (jwt_verify_claims_str (return_value , "jti" , JWT_G (jti )))
377+ FORMAT_CEX_MSG ("Invalid Jti" , jwt_invalid_jti_cex );
378+
379+ /* aud */
380+ size_t flag = 0 ;
381+ zval * zv_aud = zend_hash_str_find (Z_ARRVAL_P (return_value ), "aud" , strlen ("aud" ));
382+
383+ if (zv_aud && JWT_G (aud )) {
384+ switch (Z_TYPE_P (zv_aud )) {
385+ case IS_ARRAY :
386+ if (jwt_array_equals (Z_ARRVAL_P (JWT_G (aud )), Z_ARRVAL_P (zv_aud ))) flag = 1 ;
387+ break ;
388+ case IS_STRING :
389+ if (strcmp (Z_STRVAL_P (JWT_G (aud )), Z_STRVAL_P (zv_aud ))) flag = 1 ;
390+ break ;
391+ default :
392+ php_error_docref (NULL , E_WARNING , "Aud type must be string or array" );
393+ break ;
394+ }
380395
381- if (zv_aud && JWT_G (aud )) {
382- switch (Z_TYPE_P (zv_aud )) {
383- case IS_ARRAY :
384- if (jwt_array_equals (Z_ARRVAL_P (JWT_G (aud )), Z_ARRVAL_P (zv_aud ))) flag = 1 ;
385- break ;
386- case IS_STRING :
387- if (strcmp (Z_STRVAL_P (JWT_G (aud )), Z_STRVAL_P (zv_aud ))) flag = 1 ;
388- break ;
389- default :
390- php_error_docref (NULL , E_WARNING , "Aud type must be string or array" );
391- break ;
396+ if (flag ) FORMAT_CEX_MSG ("Invalid Aud" , jwt_invalid_aud_cex );
392397 }
393398
394- if (flag ) FORMAT_CEX_MSG ("Invalid Aud" , jwt_invalid_aud_cex );
399+ /* sub */
400+ if (jwt_verify_claims_str (return_value , "sub" , JWT_G (sub )))
401+ FORMAT_CEX_MSG ("Invalid Sub" , jwt_invalid_sub_cex );
402+ } else {
403+ FORMAT_CEX_MSG ("Json decode error" , spl_ce_UnexpectedValueException );
395404 }
396405
397- /* sub */
398- if (jwt_verify_claims_str (return_value , "sub" , JWT_G (sub )))
399- FORMAT_CEX_MSG ("Invalid Sub" , jwt_invalid_sub_cex );
400-
406+ done :
401407 if (err_msg ) {
402408 zend_throw_exception (ce , err_msg , 0 );
403409 return FAILURE ;
@@ -601,11 +607,6 @@ static void php_jwt_decode(INTERNAL_FUNCTION_PARAMETERS) {
601607 goto decode_done ;
602608 }
603609
604- /* parse body */
605- if (jwt_verify_body (body , return_value ) == FAILURE ) {
606- goto decode_done ;
607- }
608-
609610 /* verify */
610611 if (jwt -> alg == JWT_ALG_NONE ) {
611612 /* done */
@@ -622,9 +623,14 @@ static void php_jwt_decode(INTERNAL_FUNCTION_PARAMETERS) {
622623 if (jwt_verify (jwt , sig )) {
623624 zend_throw_exception (jwt_signature_invalid_cex , "Signature verification failed" , 0 );
624625 }
626+
627+ smart_str_free (& segments );
625628 }
626629
627- smart_str_free (& segments );
630+ /* verify body */
631+ if (jwt_verify_body (body , return_value ) == FAILURE ) {
632+ goto decode_done ;
633+ }
628634
629635decode_done :
630636 efree (head );
0 commit comments