@@ -6297,6 +6297,118 @@ rc = pcre2_substitute(subs_other_code, substitute_subject,
62976297 NULL , 0 , replace_buf , & sizeval );
62986298ASSERT (rc == PCRE2_ERROR_DIFFSUBSPATTERN , "pcre2_substitute(pattern)" );
62996299
6300+ /* -------------- pcre2_serialize_decode: three goto cleanup branches -------- */
6301+
6302+ {
6303+ pcre2_code * serialize_code = pcre2_compile (pattern , PCRE2_ZERO_TERMINATED ,
6304+ 0 , & errorcode , & erroroffset , NULL );
6305+ uint8_t * serialized_bytes = NULL ;
6306+ PCRE2_SIZE serialized_size = 0 ;
6307+ pcre2_code * decode_codes [1 ] = { NULL };
6308+
6309+ ASSERT (serialize_code != NULL , "serialize setup" );
6310+ rc = pcre2_serialize_encode ((const pcre2_code * * )& serialize_code , 1 ,
6311+ & serialized_bytes , & serialized_size , NULL );
6312+ pcre2_code_free (serialize_code );
6313+ ASSERT (rc == 1 && serialized_bytes != NULL , "serialize setup" );
6314+
6315+ /* goto 1: blocksize <= sizeof(pcre2_real_code) */
6316+ {
6317+ size_t blocksize_offset = sizeof (pcre2_serialized_data ) + TABLES_LENGTH +
6318+ offsetof(pcre2_real_code , blocksize );
6319+ uint8_t saved_blocksize [sizeof (PCRE2_SIZE )];
6320+ memcpy (saved_blocksize , serialized_bytes + blocksize_offset ,
6321+ sizeof (saved_blocksize ));
6322+ memset (serialized_bytes + blocksize_offset , 0 , sizeof (PCRE2_SIZE ));
6323+
6324+ rc = pcre2_serialize_decode (decode_codes , 1 , serialized_bytes , NULL );
6325+ ASSERT (rc == PCRE2_ERROR_BADSERIALIZEDDATA &&
6326+ decode_codes [0 ] == NULL , "pcre2_serialize_decode(bad blocksize)" );
6327+
6328+ memcpy (serialized_bytes + blocksize_offset , saved_blocksize ,
6329+ sizeof (saved_blocksize ));
6330+ }
6331+
6332+ /* goto 2: dst_re malloc failure */
6333+ mallocs_until_failure = 2 ;
6334+ {
6335+ pcre2_general_context * serialize_test_context =
6336+ pcre2_general_context_create (& my_malloc , & my_free , NULL );
6337+ ASSERT (serialize_test_context != NULL , "general_context for serialize test" );
6338+ rc = pcre2_serialize_decode (decode_codes , 1 , serialized_bytes ,
6339+ serialize_test_context );
6340+ ASSERT (rc == PCRE2_ERROR_NOMEMORY && decode_codes [0 ] == NULL ,
6341+ "pcre2_serialize_decode(malloc failure)" );
6342+ mallocs_until_failure = INT_MAX ;
6343+ pcre2_general_context_free (serialize_test_context );
6344+ }
6345+
6346+ /* goto 3: magic_number / name_entry_size / name_count validation */
6347+ {
6348+ size_t off = sizeof (pcre2_serialized_data ) + TABLES_LENGTH +
6349+ offsetof(pcre2_real_code , magic_number );
6350+ uint8_t saved [4 ];
6351+ memcpy (saved , serialized_bytes + off , 4 );
6352+ memset (serialized_bytes + off , 0 , 4 );
6353+
6354+ decode_codes [0 ] = NULL ;
6355+ rc = pcre2_serialize_decode (decode_codes , 1 , serialized_bytes , NULL );
6356+ memcpy (serialized_bytes + off , saved , 4 );
6357+ ASSERT (rc == PCRE2_ERROR_BADSERIALIZEDDATA &&
6358+ decode_codes [0 ] == NULL , "pcre2_serialize_decode(goto 3)" );
6359+ }
6360+
6361+ /* Regression: avoid stale dst_re double free on later iteration failure. */
6362+ {
6363+ pcre2_code * multi_codes [2 ];
6364+ pcre2_code * multi_decode_codes [2 ] = { NULL , NULL };
6365+ uint8_t * multi_serialized_bytes = NULL ;
6366+ PCRE2_SIZE multi_serialized_size = 0 ;
6367+ CODE_BLOCKSIZE_TYPE first_blocksize ;
6368+ size_t first_blocksize_offset = sizeof (pcre2_serialized_data ) +
6369+ TABLES_LENGTH + offsetof(pcre2_real_code , blocksize );
6370+ size_t second_blocksize_offset ;
6371+ uint8_t saved_second_blocksize [sizeof (CODE_BLOCKSIZE_TYPE )];
6372+
6373+ multi_codes [0 ] = pcre2_compile (pattern , PCRE2_ZERO_TERMINATED , 0 ,
6374+ & errorcode , & erroroffset , NULL );
6375+ multi_codes [1 ] = pcre2_compile (pattern , PCRE2_ZERO_TERMINATED , 0 ,
6376+ & errorcode , & erroroffset , NULL );
6377+ ASSERT (multi_codes [0 ] != NULL && multi_codes [1 ] != NULL ,
6378+ "serialize setup (multi-code compile)" );
6379+
6380+ rc = pcre2_serialize_encode ((const pcre2_code * * )multi_codes , 2 ,
6381+ & multi_serialized_bytes , & multi_serialized_size , NULL );
6382+ pcre2_code_free (multi_codes [0 ]);
6383+ pcre2_code_free (multi_codes [1 ]);
6384+ ASSERT (rc == 2 && multi_serialized_bytes != NULL ,
6385+ "serialize setup (multi-code encode)" );
6386+
6387+ memcpy (& first_blocksize , multi_serialized_bytes + first_blocksize_offset ,
6388+ sizeof (first_blocksize ));
6389+ second_blocksize_offset = sizeof (pcre2_serialized_data ) + TABLES_LENGTH +
6390+ first_blocksize + offsetof(pcre2_real_code , blocksize );
6391+
6392+ memcpy (saved_second_blocksize ,
6393+ multi_serialized_bytes + second_blocksize_offset ,
6394+ sizeof (saved_second_blocksize ));
6395+ memset (multi_serialized_bytes + second_blocksize_offset , 0 ,
6396+ sizeof (saved_second_blocksize ));
6397+
6398+ rc = pcre2_serialize_decode (multi_decode_codes , 2 , multi_serialized_bytes ,
6399+ NULL );
6400+ memcpy (multi_serialized_bytes + second_blocksize_offset ,
6401+ saved_second_blocksize , sizeof (saved_second_blocksize ));
6402+ ASSERT (rc == PCRE2_ERROR_BADSERIALIZEDDATA &&
6403+ multi_decode_codes [0 ] == NULL && multi_decode_codes [1 ] == NULL ,
6404+ "pcre2_serialize_decode(regression stale dst_re)" );
6405+
6406+ pcre2_serialize_free (multi_serialized_bytes );
6407+ }
6408+
6409+ pcre2_serialize_free (serialized_bytes );
6410+ }
6411+
63006412/* ------------------------------------------------------------------------- */
63016413
63026414#undef ASSERT
0 commit comments