@@ -44,6 +44,12 @@ static void js_vm_set_prepare_stage(const char *s) {
4444 js_vm_last_prepare_stage [n ] = 0 ;
4545}
4646
47+ static int js_vm_prepare_stage_has_prefix (const char * prefix ) {
48+ if (!prefix ) return 0 ;
49+ size_t n = strlen (prefix );
50+ return n > 0 && strncmp (js_vm_last_prepare_stage , prefix , n ) == 0 ;
51+ }
52+
4753JS_HIDDEN unsigned char * js_vbc4_zstd_decompress_owned (const unsigned char * stored , uint32_t stored_len , uint32_t plain_len ) {
4854 if (!stored || stored_len == 0 ) return NULL ;
4955 if (stored_len == plain_len ) {
@@ -621,15 +627,15 @@ JS_PROTECTED static int js_manifest_order_token(const char *mesh, uint32_t ordin
621627JS_HIDDEN unsigned char * js_vm_reassemble_sliced_resource (JNIEnv * env , jclass helper_cls , unsigned char * decoded , int decoded_len , int * out_len ) {
622628 if (!decoded || decoded_len < 10 || !out_len || memcmp (decoded , "VBC4S|1|" , 8 ) != 0 ) return decoded ;
623629 char * manifest = (char * )calloc ((size_t )decoded_len + 1u , 1u );
624- if (!manifest ) return NULL ;
630+ if (!manifest ) { js_vm_set_prepare_stage ( "reassemble-manifest-alloc" ); return NULL ; }
625631 memcpy (manifest , decoded , (size_t )decoded_len );
626632 js_vbc4_wipe_volatile (decoded , (size_t )decoded_len );
627633 free (decoded );
628634 decoded = NULL ;
629635
630636 char * line = manifest ;
631637 char * next_line = strchr (line , '\n' );
632- if (!next_line ) { js_vbc4_wipe_volatile (manifest , (size_t )decoded_len ); free (manifest ); return NULL ; }
638+ if (!next_line ) { js_vm_set_prepare_stage ( "reassemble-manifest-newline" ); js_vbc4_wipe_volatile (manifest , (size_t )decoded_len ); free (manifest ); return NULL ; }
633639 * next_line ++ = 0 ;
634640 char * cursor = line ;
635641 char * magic = js_next_manifest_field (& cursor );
@@ -649,10 +655,12 @@ JS_HIDDEN unsigned char* js_vm_reassemble_sliced_resource(JNIEnv *env, jclass he
649655 !js_parse_u32_token (entry_count_text , & manifest_entry_count ) || manifest_entry_count == 0 ||
650656 manifest_ordinal >= manifest_entry_count || total_len == 0 || shard_count < 2 || shard_count > 16 ||
651657 total_len > 64u * 1024u * 1024u ) {
658+ js_vm_set_prepare_stage ("reassemble-header" );
652659 js_vbc4_wipe_volatile (manifest , (size_t )decoded_len ); free (manifest ); return NULL ;
653660 }
654661 unsigned char mesh_digest_bytes [32 ];
655662 if (!js_hex32_to_bytes (mesh_text , mesh_digest_bytes )) {
663+ js_vm_set_prepare_stage ("reassemble-mesh-digest" );
656664 js_vbc4_wipe_volatile (mesh_digest_bytes , sizeof (mesh_digest_bytes ));
657665 js_vbc4_wipe_volatile (manifest , (size_t )decoded_len ); free (manifest ); return NULL ;
658666 }
@@ -661,6 +669,7 @@ JS_HIDDEN unsigned char* js_vm_reassemble_sliced_resource(JNIEnv *env, jclass he
661669 unsigned char * seen = (unsigned char * )calloc ((size_t )shard_count , 1u );
662670 char (* order_tokens )[17 ] = (char (* )[17 ])calloc ((size_t )shard_count , sizeof (* order_tokens ));
663671 if (!assembled || !seen || !order_tokens ) {
672+ js_vm_set_prepare_stage ("reassemble-alloc" );
664673 if (assembled ) free (assembled );
665674 if (seen ) free (seen );
666675 if (order_tokens ) free (order_tokens );
@@ -691,19 +700,22 @@ JS_HIDDEN unsigned char* js_vm_reassemble_sliced_resource(JNIEnv *env, jclass he
691700 length > total_len - offset || !sha_text || strlen (sha_text ) != 64 ||
692701 !js_hex32_to_bytes (sha_text , expected_sha ) || !path_text || !path_text [0 ] ||
693702 !js_hex16_is_valid (mesh_link_text ) || !js_hex16_is_valid (peer_link_text )) {
703+ js_vm_set_prepare_stage ("reassemble-row" );
694704 ok = 0 ;
695705 } else {
696706 char expected_order_token [17 ];
697707 if (!js_manifest_mesh_link_matches (mesh_text , manifest_ordinal , index , offset , length , sha_text , path_text , mesh_link_text ) ||
698708 !js_manifest_peer_link_matches (mesh_text , manifest_ordinal , manifest_entry_count , index , offset , length , sha_text , path_text , peer_ordinal , peer_link_text ) ||
699709 !js_manifest_order_token (mesh_text , manifest_ordinal , index , path_text , sha_text , expected_order_token ) ||
700710 (loaded_count > 0 && strcmp (order_tokens [loaded_count - 1 ], expected_order_token ) > 0 )) {
711+ js_vm_set_prepare_stage ("reassemble-mesh-link" );
701712 ok = 0 ;
702713 }
703714 if (ok ) memcpy (order_tokens [loaded_count ], expected_order_token , sizeof (expected_order_token ));
704715 int shard_len = 0 ;
705716 unsigned char * shard = js_vm_decode_resource_path_owned (env , helper_cls , path_text , & shard_len );
706717 if (!shard || shard_len != (int )length ) {
718+ js_vm_set_prepare_stage ("reassemble-shard-load" );
707719 ok = 0 ;
708720 } else {
709721 unsigned char actual_sha [32 ];
@@ -712,6 +724,7 @@ JS_HIDDEN unsigned char* js_vm_reassemble_sliced_resource(JNIEnv *env, jclass he
712724 js_sha256_update (& sha_ctx , shard , shard_len );
713725 js_sha256_final (& sha_ctx , actual_sha );
714726 if (memcmp (actual_sha , expected_sha , 32 ) != 0 ) {
727+ js_vm_set_prepare_stage ("reassemble-shard-digest" );
715728 ok = 0 ;
716729 } else {
717730 memcpy (assembled + offset , shard , (size_t )length );
@@ -726,8 +739,8 @@ JS_HIDDEN unsigned char* js_vm_reassemble_sliced_resource(JNIEnv *env, jclass he
726739 }
727740 line = line_end ? line_end + 1 : NULL ;
728741 }
729- for (uint32_t i = 0 ; ok && i < shard_count ; i ++ ) if (!seen [i ]) ok = 0 ;
730- if (loaded_count != shard_count ) ok = 0 ;
742+ for (uint32_t i = 0 ; ok && i < shard_count ; i ++ ) if (!seen [i ]) { js_vm_set_prepare_stage ( "reassemble-missing-shard" ); ok = 0 ; }
743+ if (loaded_count != shard_count ) { js_vm_set_prepare_stage ( "reassemble-count" ); ok = 0 ; }
731744 js_vbc4_wipe_volatile (order_tokens , (size_t )shard_count * sizeof (* order_tokens ));
732745 free (order_tokens );
733746 js_vbc4_wipe_volatile (seen , (size_t )shard_count );
@@ -872,7 +885,7 @@ JS_HIDDEN js_vm_program* js_vm_prepare_resource_program_bound(JNIEnv *env, jclas
872885 }
873886 decoded = js_vm_reassemble_sliced_resource (env , resource_cls , decoded , decoded_len , & decoded_len );
874887 if (!decoded ) {
875- js_vm_set_prepare_stage ("reassemble" );
888+ if (! js_vm_prepare_stage_has_prefix ( "reassemble-" )) js_vm_set_prepare_stage ("reassemble" );
876889 rls (env , resourcePath , resource_path );
877890 return NULL ;
878891 }
0 commit comments