diff --git a/ChangeLog b/ChangeLog index 07986b4f4..9abaeb159 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2012-03-07 Moritz Bunkus + + * mkvmerge: bug fix: SRT subtitles: timecodes can contain the + minus sign before any digit, not just before the first one. + 2012-03-05 Moritz Bunkus * mkvmerge: bug fix: Sometimes non-AC3 files were mistakenly for diff --git a/src/input/subtitles.cpp b/src/input/subtitles.cpp index bfdeb81c1..1a14ccde6 100644 --- a/src/input/subtitles.cpp +++ b/src/input/subtitles.cpp @@ -37,7 +37,8 @@ subtitles_c::process(generic_packetizer_c *p) { // ------------------------------------------------------------ -#define SRT_RE_TIMECODE "\\s*(-?)\\s*(\\d+):\\s*(\\d+):\\s*(\\d+)[,\\.]\\s*(\\d+)?" +#define SRT_RE_VALUE "\\s*(-?)\\s*(\\d+)" +#define SRT_RE_TIMECODE SRT_RE_VALUE ":" SRT_RE_VALUE ":" SRT_RE_VALUE "[,\\.]" SRT_RE_VALUE #define SRT_RE_TIMECODE_LINE "^" SRT_RE_TIMECODE "\\s*-+>\\s*" SRT_RE_TIMECODE "\\s*" #define SRT_RE_COORDINATES "([XY]\\d+:\\d+\\s*){4}\\s*$" @@ -136,18 +137,28 @@ srt_parser_c::parse() { int s_h, s_min, s_sec, e_h, e_min, e_sec; - parse_int(matches[2].str(), s_h); - parse_int(matches[3].str(), s_min); - parse_int(matches[4].str(), s_sec); - parse_int(matches[7].str(), e_h); - parse_int(matches[8].str(), e_min); - parse_int(matches[9].str(), e_sec); + // 1 2 3 4 5 6 7 8 + // "\\s*(-?)\\s*(\\d+):\\s(-?)*(\\d+):\\s*(-?)(\\d+)[,\\.]\\s*(-?)(\\d+)?" - std::string s_rest = matches[ 5].str(); - std::string e_rest = matches[10].str(); + parse_int(matches[ 2].str(), s_h); + parse_int(matches[ 4].str(), s_min); + parse_int(matches[ 6].str(), s_sec); + parse_int(matches[10].str(), e_h); + parse_int(matches[12].str(), e_min); + parse_int(matches[14].str(), e_sec); - int64_t s_neg = matches[ 1].str() == "-" ? -1 : 1; - int64_t e_neg = matches[ 6].str() == "-" ? -1 : 1; + std::string s_rest = matches[ 8].str(); + std::string e_rest = matches[16].str(); + + auto neg_calculator = [&](size_t const start_idx) { + int64_t neg = 1; + for (size_t idx = start_idx; idx <= (start_idx + 6); idx += 2) + neg *= matches[idx].str() == "-" ? -1 : 1; + return neg; + }; + + int64_t s_neg = neg_calculator(1); + int64_t e_neg = neg_calculator(9); if (boost::regex_search(s, coordinates_re) && !m_coordinates_warning_shown) { mxwarn_tid(m_file_name, m_tid, diff --git a/tests/results.txt b/tests/results.txt index c4135551e..77c728d43 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -192,3 +192,4 @@ T_343m2ts_interlaced_h264_match_of_the_day:fdab49f2f33981826793bb66aab97ca5:pass T_344microdvd_recognition:ok:passed:20120304-175209:0.082792556 T_345flag_enabled:efe07b85cd349a040ed79402256bd6ea-89e9b90881c73d55ac4eda07e20effe5:passed:20120304-181150:0.135757829 T_347h264_misdetected_as_ac3:4dcd5541b962ce1d534e04481deadbec:passed:20120305-160017:2.617159557 +T_348srt_negative_timecodes2:4fc486c9de77896d9f8c2cf997d88d8c:passed:20120307-115726:0.085988974 diff --git a/tests/test-348srt_negative_timecodes2.rb b/tests/test-348srt_negative_timecodes2.rb new file mode 100644 index 000000000..31bfe53b1 --- /dev/null +++ b/tests/test-348srt_negative_timecodes2.rb @@ -0,0 +1,6 @@ +#!/usr/bin/ruby -w + +# T_348srt_negative_timecodes2 +describe "mkvmerge / SRT subitles with negative timecodes" + +test_merge "data/srt/negative_timecodes2.srt", :exit_code => 1