kax_analyzer_c: fix creating voids for gaps of 130 bytes

A two-byte header field (one for the ID, one for the content size) can
have a content size of at most 127 bytes, meaning a total size of 129 is
easy to achieve: set the content size to 127 bytes, libEBML will
calculate the required length of the content size field to be 1 and the
resulting element's total size will be the desired 129 bytes.

A content size of 128 would mean that the content size field must be at
least two bytes long. Taking the element's ID into account this would
mean a total element size of 128 + 2 + 1 = 131 bytes. So getting libEBML
to produce an element of a total size of 131 is easy, too: set the
content size to 128 bytes, and libEBML will do the rest.

The problematic total size is a 130 bytes. There simply is no content
size for which adding the minimal length of the content size field and 1
for the ID would result in a total size of 130 bytes.

The solution is writing the length field with more bytes than
necessary. In the case of a total size of 130 bytes we could use the
maximum one-byte content size = 127 bytes, add one byte for the ID and
force the content size field's length to be two instead of one
byte (0x407f instead of 0xff).

Similar corner cases exist for the transition between content size field
being two/three bytes, three/four bytes long etc. In order to keep the
code simple we always use an eight-bytes long content size field if the
total size is at least nine bytes and a one-byte long content size field
otherwise.
This commit is contained in:
Moritz Bunkus 2015-02-23 20:56:27 +01:00
parent 56357aa31c
commit 8d78387b09
4 changed files with 69 additions and 11 deletions

View File

@ -1,5 +1,10 @@
2015-02-23 Moritz Bunkus <moritz@bunkus.org>
* mkvpropedit, mmg's header editor: bug fix: if updating the file
required creating an EBML void for a 130 bytes long gap then the
void element created was one byte too short resulting in an
invalid file structure. Fixes #1121.
* mkvmerge: bug fix: If the MP4 track headers for MP3 tracks
contain invalid values (number of channels is 0 or the sampling
rate is 0) then mkvmerge will re-derive these parameters from the

View File

@ -560,10 +560,53 @@ kax_analyzer_c::handle_void_elements(size_t data_idx) {
m_file->setFilePointer(void_pos);
// Yes. Write a new EbmlVoid element and update the internal records.
// Calculating the void element's content size. This is not straight
// forward because there are special values for the total size for
// which the header size must be forced to be one byte more than would
// be strictly necessary in order to occupy the space. Here's an
// example:
// A two-byte header field (one for the ID, one for the content
// size) can have a content size of at most 127 bytes, meaning a
// total size of 129 is easy to achieve: set the content size to 127
// bytes, libEBML will calculate the required length of the content
// size field to be 1 and the resulting element's total size will be
// the desired 129 bytes.
// A content size of 128 would mean that the content size field must be
// at least two bytes long. Taking the element's ID into account this
// would mean a total element size of 128 + 2 + 1 = 131 bytes. So
// getting libEBML to produce an element of a total size of 131 is
// easy, too: set the content size to 128 bytes, and libEBML will do
// the rest.
// The problematic total size is a 130 bytes. There simply is no
// content size for which adding the minimal length of the content
// size field and 1 for the ID would result in a total size of 130
// bytes.
// The solution is writing the length field with more bytes than
// necessary. In the case of a total size of 130 bytes we could use
// the maximum one-byte content size = 127 bytes, add one byte for the
// ID and force the content size field's length to be two instead of
// one byte (0x407f instead of 0xff).
// Similar corner cases exist for the transition between content
// size field being two/three bytes, three/four bytes long etc. In
// order to keep the code simple we always use an eight-bytes long
// content size field if the total size is at least nine bytes and a
// one-byte long content size field otherwise.
EbmlVoid evoid;
evoid.SetSize(void_size);
evoid.UpdateSize();
evoid.SetSize(void_size - evoid.HeadSize());
if (void_size < 9)
evoid.SetSize(void_size - 2);
else {
evoid.SetSize(void_size - 9);
evoid.SetSizeLength(8);
}
evoid.Render(*m_file);
m_data.insert(m_data.begin() + data_idx + 1, kax_analyzer_data_c::create(EBML_ID(EbmlVoid), void_pos, void_size));

View File

@ -125,7 +125,7 @@ T_276h264_without_nalus_in_avi:4066d5121ee2b23f1a7f3bb78394aec5:passed:20100706-
T_277display_dimensions_fixing_aspect_ratio_usage:a64c12a150de6215b3251cff4294289b-feff2b3adc4d7d17f74c4c4ebe348642-865b5e6d1757cdfb1664616cba57cd85:passed:20100718-201627:2.064719998
T_278turning_off_compression:64917eb3a9c27a83248f0e9e5d67349d-64917eb3a9c27a83248f0e9e5d67349d:passed:20100728-121842:0.662304078
T_279packet_queue_not_empty_ivf:492aea08e2a74c55e41601c779388067:passed:20100805-230439:0.107456716
T_280replace_one_byte_with_ebmlvoid:9cfa2af2712e48f43f35497f4e9bec24:passed:20100824-201249:0.21509374
T_280replace_one_byte_with_ebmlvoid:9e902c6b32b9238a67c88051c6edb6d6:passed:20100824-201249:0.21509374
T_281idr_after_non_idr_not_recognized:e7139e3b561385bb128bca7830418bac:passed:20100828-194029:1.222172253
T_282mkvextract_error_on_non_existing_file:true:passed:20100901-230139:0.032414822
T_283no_video_on_avi:f2df4943647d7118bbecc107aa4d98fa:passed:20100919-111902:0.063610211
@ -167,10 +167,10 @@ T_318ui_locale_invalid:ok:passed:20111016-192531:0.021014802
T_319wav_with_pcm_detected_as_dts:e5c7882e523a2c27e496a9e8d4db5a76:passed:20111016-224416:0.059853624
T_320ts_aac:0745409318b0414a030df755586e07ee:passed:20111022-140411:0.693145547
T_321vc1_without_markers:636d3bf99a30613054b5bb15e08d9973:passed:20111104-003839:1.584477691
T_322propedit_track_headers:785209f2dc35ad6177bea2ca6e43198f-9896cdb0b3116d8c1710adc313e5f23f-a7c535942a970f57eeea541eb3e07c9d-f9f403d6049a684fd793c7c56af811c2-abf1ea5dd3f88da41b8dcbb37998d4c5:passed:20111203-152145:0.677404829
T_323propedit_segment_info:785209f2dc35ad6177bea2ca6e43198f-2df9da2d502a7d5ad914966c27393844-c65579659de3fb44c74aed6965b5ce2e:passed:20111203-152845:0.425794709
T_324propedit_chapters:785209f2dc35ad6177bea2ca6e43198f-a9255d40de93e2731aaead0a746e582f-a6d99a5e779aa1c65ba4d03597754d37-ae788bbd0580dd01d10672a46e3be84d-2a53e52d0e3b13d37f5e9f411a9e74eb-b6aafbfe2bc4902f3187031a71730f8d-ee5f4977886284f0d97519895fbab9d8-48614f8c72edb5d3e23115e1998f5997-11d7efba28fe0cd85b03919dd87324e9-d41d8cd98f00b204e9800998ecf8427e:passed:20111203-154502:0.736303091
T_325propedit_tags:785209f2dc35ad6177bea2ca6e43198f-26ad4ab0491d76d9fb6f57b4a4b35400-e58a5937ac6e0dc71d6c8264c53535be-52322241c33de4f7b56ede7a4764f72f-e58a5937ac6e0dc71d6c8264c53535be-52322241c33de4f7b56ede7a4764f72f-e26ce3a9725c74e16b5be99a5a917ae2-591a65deb231cb0150a4da224d5f3415-8aa2fda41ba5c0cfe6fec3d46611896c-438f0a8ce757e03b77c084bd593cb196-8aa2fda41ba5c0cfe6fec3d46611896c-438f0a8ce757e03b77c084bd593cb196-1e335b1d4a8ed48cbaa4efcffecdba28-5a8f05d63ffe9d53046abf40ec30e42a-54597c44d0938662d716edd21e4d6c68-d41d8cd98f00b204e9800998ecf8427e:passed:20111203-160727:1.314514241
T_322propedit_track_headers:785209f2dc35ad6177bea2ca6e43198f-3e9ff1255235f31945c986b1f706d068-bffedbf97e9a1cd873ba48a6651483a7-69fc3f48fb53badf1ca224582e4eb7ff-04192d839e6db3ff4e3de3ecbdac274e:passed:20111203-152145:0.677404829
T_323propedit_segment_info:785209f2dc35ad6177bea2ca6e43198f-0baf1cb46e7d365580b51aa4452551d6-d6cd21681b8544aa730744f128d46fd7:passed:20111203-152845:0.425794709
T_324propedit_chapters:785209f2dc35ad6177bea2ca6e43198f-a9255d40de93e2731aaead0a746e582f-493859725ffbe8bf65cfd397e26a7c90-ae788bbd0580dd01d10672a46e3be84d-9ff842a7f02fe26ef95313b626be83b3-b6aafbfe2bc4902f3187031a71730f8d-3057bf142672a2c86657c64f4e4d189a-48614f8c72edb5d3e23115e1998f5997-8594e3734741654285cc5ce5e48f3e29-d41d8cd98f00b204e9800998ecf8427e:passed:20111203-154502:0.736303091
T_325propedit_tags:785209f2dc35ad6177bea2ca6e43198f-26ad4ab0491d76d9fb6f57b4a4b35400-2d6bc3c519e65853430cd53e64d46386-52322241c33de4f7b56ede7a4764f72f-2d6bc3c519e65853430cd53e64d46386-52322241c33de4f7b56ede7a4764f72f-ddb1f5475eca068a3e4b6ad8df1dea7e-591a65deb231cb0150a4da224d5f3415-e657d1255b0b7a1a1610bda7460dc318-438f0a8ce757e03b77c084bd593cb196-e657d1255b0b7a1a1610bda7460dc318-438f0a8ce757e03b77c084bd593cb196-6f60e83c7d351a25ad6af4545ce3dff6-5a8f05d63ffe9d53046abf40ec30e42a-e126ac5e6a97297f4ee14cfd648e1e33-d41d8cd98f00b204e9800998ecf8427e:passed:20111203-160727:1.314514241
T_326mpeg_ps_mpeg_audio_layer4:92c7507e54caf041d729c2e9e97c775f:passed:20111207-224511:1.505513342
T_327vp8_frame_type:da02f5873c366315b4594e34a04966e8:passed:20111207-233304:0.089263543
T_328dts_detected_as_ac3:98e9459b6ed0857cd8c9b526eab609b9:passed:20111229-192324:0.090561076
@ -215,7 +215,7 @@ T_366srt_with_space_in_timecode_arrow:ad8e2cdf5de8ba4b845ac4894ef7296b:passed:20
T_367vob_80ms_delay_by_b_frames:f198c5e9e7382ae920df79e850433a02-4843b0199b3701b6f92d42d1092a5c60:passed:20120801-182507:0.106468603
T_368alac:ef55ca2ffd57f92348ebc9ebff011c10-c150a9b2183810011fa20961cf7de72f-a4cdc118b8e884218dc2bd8191b28b46-1f07d381ad4911f3b7a93b92e439f238:passed:20120805-160128:0.596006157
T_369mpeg_ts_timecode_overflow:dad433a329b71402825dba52f175bfdc:passed:20120807-120810:5.138361997
T_370propedit_attachments:c46cf09b802aabfa1e75eb7d2942fd47-c46cf09b802aabfa1e75eb7d2942fd47-027ffb91c0720e5fadd5668706c9fd00-c46cf09b802aabfa1e75eb7d2942fd47-027ffb91c0720e5fadd5668706c9fd00-c46cf09b802aabfa1e75eb7d2942fd47-027ffb91c0720e5fadd5668706c9fd00-c46cf09b802aabfa1e75eb7d2942fd47-6b854aac51eda44afb53704e3b9b75a6-c46cf09b802aabfa1e75eb7d2942fd47-7c4661149dcdb26b78d4c20dc5102ae8-c46cf09b802aabfa1e75eb7d2942fd47-d5ddd11843b0178852422aa974a2bfdd-c46cf09b802aabfa1e75eb7d2942fd47-bd3a356ac0bcd25a2653d3dff6e01cf1-c46cf09b802aabfa1e75eb7d2942fd47-11890550ecb5faa7e515b7a8740ee99d-c46cf09b802aabfa1e75eb7d2942fd47-313c845d98fcf415736425b52fca942f-c46cf09b802aabfa1e75eb7d2942fd47-c988f43d86ed87d232e00e5c6b3305ff-c46cf09b802aabfa1e75eb7d2942fd47-c988f43d86ed87d232e00e5c6b3305ff-c46cf09b802aabfa1e75eb7d2942fd47-4d99849c47883e49f97b4aca9900d2e0-c46cf09b802aabfa1e75eb7d2942fd47-7280dd103ba69fd49557c67c1fa65357-c46cf09b802aabfa1e75eb7d2942fd47-7d9fd9ad1ed9dc37dcdfc33fde81a782-c46cf09b802aabfa1e75eb7d2942fd47-7d9fd9ad1ed9dc37dcdfc33fde81a782-c46cf09b802aabfa1e75eb7d2942fd47-c1c5639bcbef470919f5883cc96dc5da-c46cf09b802aabfa1e75eb7d2942fd47-37fc8a2602c2c10f1c05da34aed7f6d1-c46cf09b802aabfa1e75eb7d2942fd47-a2df3a34ef0436db1036a41decd2b791:passed:20120902-110003:0.73777194
T_370propedit_attachments:c46cf09b802aabfa1e75eb7d2942fd47-c46cf09b802aabfa1e75eb7d2942fd47-f7429279ccfd92cf34e3601df7e73f92-c46cf09b802aabfa1e75eb7d2942fd47-f7429279ccfd92cf34e3601df7e73f92-c46cf09b802aabfa1e75eb7d2942fd47-f7429279ccfd92cf34e3601df7e73f92-c46cf09b802aabfa1e75eb7d2942fd47-e581622ae82cec97cad72c14ab13c345-c46cf09b802aabfa1e75eb7d2942fd47-d4c8f29d836e03d3f8ef5654deb03ab7-c46cf09b802aabfa1e75eb7d2942fd47-7cf0f5ee42bd0b7860218e4adf35d1bc-c46cf09b802aabfa1e75eb7d2942fd47-71b991a449ba5d5950c4fbd8a7e049fd-c46cf09b802aabfa1e75eb7d2942fd47-6ab0ae50b57b7fbe27d6e8fbd39657a8-c46cf09b802aabfa1e75eb7d2942fd47-8e86ece172037e0da052b8a4743680d3-c46cf09b802aabfa1e75eb7d2942fd47-97f248468242b41b2db10606d0200859-c46cf09b802aabfa1e75eb7d2942fd47-97f248468242b41b2db10606d0200859-c46cf09b802aabfa1e75eb7d2942fd47-ce8efa910e19a4db9a24eab3a3d5a798-c46cf09b802aabfa1e75eb7d2942fd47-63fb3e154379f47f85a471e7acdd854a-c46cf09b802aabfa1e75eb7d2942fd47-5dda85159a4abaab9e7b0606858ff282-c46cf09b802aabfa1e75eb7d2942fd47-5dda85159a4abaab9e7b0606858ff282-c46cf09b802aabfa1e75eb7d2942fd47-ee207f027b29c9b31fee1e4344fc3e16-c46cf09b802aabfa1e75eb7d2942fd47-b33199b2d2b64923228a79345bf18772-c46cf09b802aabfa1e75eb7d2942fd47-8ecad07d5c53cc05ee9502c1f7ea260d:passed:20120902-110003:0.73777194
T_371doc_and_read_version:4+2-4+2-3+2-3+2-2+2-3+1-3+1-1+1:passed:20120927-110447:1.294617251
T_372ui_locale_eu_ES:cd0927f0c4248d14b97336097ee36c2e-8ef1b15c1dcfa5a888fab14cdeec0cda:passed:20120930-150340:0.096365772
T_373reading_linked_seek_heads:1b7c63bb3cb623828d9c4dc89e355e04:passed:20121202-120608:0.373994416
@ -265,7 +265,7 @@ T_416dts_in_mp4:1c845a9e728c4d75d19af048fd0a82e0-8630ebfbf51af2e73f8e704f0b529ce
T_417mkvextract_tracks_at_end_of_file:b3bb67d316e20da12926d5c1d628f6e5:passed:20131229-122704:0.04690235
T_418ac3_frame_size_0:b23aa6757e9417e78beae2eefe5174c5:passed:20131230-233047:4.297033387
T_419mov_pcm_sample_size_1_sample_table_empty:a0c597d9f15da1435a072b71123b4166:passed:20140101-221519:0.052961521
T_420matroska_attachment_no_fileuid:16de24cec7c34f9532062bf55a8a3ae1-552b6bfab098f531c54131dfc76eadaa-6fe0517dd519d6adf37c0769354b8ed6:passed:20140111-200918:0.092631489
T_420matroska_attachment_no_fileuid:16de24cec7c34f9532062bf55a8a3ae1-552b6bfab098f531c54131dfc76eadaa-59ccf9ce6587aa603e3083077c1b0aa3:passed:20140111-200918:0.092631489
T_421svq3_from_mov:60eb1b17c9d61882d3a1e7f4d1e08cfa:passed:20140112-124559:0.195365669
T_422ac3_rederive_track_parameters_from_bitstream:48cdc3df5a582034fe5b600c0eb35913:passed:20140215-162358:0.231506136
T_423deprecated_iso639_codes:937b447e63d8376c8aa665ac53d7fc6a-good-775f9173c621d890f55aabe4caa8aa10-good-571a6e8780beb166430c66ffc3fb0c65-good-4747bd83746cbbc9ebf7d6b877ae9d87-good:passed:20140222-185414:0.243526271
@ -279,7 +279,7 @@ T_430cues_multiple_blocks_same_timecode:f1ab5c927064537eb59ab0f5195d6a1d:passed:
T_431ssa_comments_exclamation_mark:3caa9ad1716134cc1f3e229b88ff94ea:passed:20140618-232324:0.072735677
T_432concatenate_two_ac3_files:4f4b7c58d4557d52849866e1a3ad1b05:passed:20140727-124637:0.15390456
T_433matroska_no_track_uid:32eaa074a254eab81b90bd97be50c425:passed:20140809-211544:0.043556355
T_434mkvpropedit_no_track_uid:99631d7c0f79faf45a37696dae506b21-0c411b1fc48d546f9fbeb6185e43f74f:passed:20140809-213018:0.046441804
T_434mkvpropedit_no_track_uid:99631d7c0f79faf45a37696dae506b21-ab7b3ff004b7ed5a188fafbc7b2d3221:passed:20140809-213018:0.046441804
T_435mp4_edit_list_duration_uses_global_time_scale:eba0b6ddc51c05e4a97f39a3bb350b01:passed:20140905-183027:0.096674624
T_436extract_ssa_extradata_after_events:8be4c4af0a2d65826071aee718ec44e8:passed:20140906-090602:0.054263072
T_437ac3_from_avi_with_garbage:507ef5ec20f908215809174355f5c7f9:passed:20140908-144311:0.075599921
@ -310,3 +310,4 @@ T_461truehd_from_mpeg_ts:c1ee4dc0746b9a3bea90ab49dd65e6a1-29f5c91656812569fb5e1f
T_462dtshd_reduce_to_core:c284b0e29c3b7040e14b89a7e4790ce1-1e8b4d2eac574607bbaa54e4b8eee9e0-1e8b4d2eac574607bbaa54e4b8eee9e0:passed:20150212-223839:1.367529862
T_463a_ms_acm_with_track_tags:7766fe047ed88b8561caa4fba7c40ea6-45aa68321f4c3785d2e38ddbfd7cd850:passed:20150218-142924:0.139369636
T_464mp4_mp3_track_sampling_rate_0:51ec17a6dcfae5d8ac0f5fcf44e31eb6-b2c1dca03505c75c694c0de113a450f6:passed:20150223-190257:0.939161518
T_465propedit_gaps_of_130_bytes:aaee6a36641e36dc3976c9e505b645da:passed:20150223-210006:0.085134008

View File

@ -0,0 +1,9 @@
#!/usr/bin/ruby -w
describe "mkvpropedit / create voids for 130 bytes long gaps"
test "propedit" do
sys "cp data/mkv/propedit-gaps-130-bytes.mkv #{tmp}"
propedit tmp, "--edit track:s1 --set flag-default=0"
hash_tmp
end