Skip to content

Commit 578abca

Browse files
authored
[FIX] Fix ownership of default Matroska track language (#2193)
* Fix ownership of default Matroska track language * matroska: restore lang_ietf preference in filename gen and lang matching Restore the working IETF language preference that was accidentally removed in the previous commit: - generate_filename_from_track(): use lang_ietf ? lang_ietf : lang for buffer sizing and both snprintf calls - save_vobsub_track(): same lang_tag pattern for base filename - matroska_save_all(): check lang_ietf first (BCP-47), fall back to lang (ISO-639-2) when --mkvlang filter is active; remove now-unused char *match variable The strdup NULL check and broken switch-case removal from the prior commit are unchanged. * matroska: fix clang-format style * matroska: fix filename underscores, LLD macro, braces, param name
1 parent 5c87a33 commit 578abca

1 file changed

Lines changed: 26 additions & 43 deletions

File tree

src/lib_ccx/matroska.c

Lines changed: 26 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -880,6 +880,10 @@ void parse_segment_track_entry(struct matroska_ctx *mkv_ctx)
880880
ULLONG track_number = 0;
881881
enum matroska_track_entry_type track_type = MATROSKA_TRACK_TYPE_VIDEO;
882882
char *lang = strdup("eng");
883+
if (lang == NULL)
884+
{
885+
fatal(EXIT_NOT_ENOUGH_MEMORY, "In parse_segment_track_entry: Out of memory allocating default language.");
886+
}
883887
char *header = NULL;
884888
char *lang_ietf = NULL;
885889
char *codec_id_string = NULL;
@@ -1031,29 +1035,7 @@ void parse_segment_track_entry(struct matroska_ctx *mkv_ctx)
10311035
case MATROSKA_SEGMENT_TRACK_LANGUAGE_IETF:
10321036
lang_ietf = read_vint_block_string(file);
10331037
mprint(" Language IETF: %s\n", lang_ietf);
1034-
// We'll store this for later use rather than freeing it immediately
1035-
if (track_type == MATROSKA_TRACK_TYPE_SUBTITLE)
1036-
{
1037-
// Don't free lang_ietf here, store in track
1038-
if (lang != NULL)
1039-
{
1040-
// If we previously allocated lang, free it as we'll prefer IETF
1041-
free(lang);
1042-
lang = NULL;
1043-
}
1044-
// Default to "eng" if we somehow don't have a language yet
1045-
if (lang == NULL)
1046-
{
1047-
lang = strdup("eng");
1048-
}
1049-
}
1050-
else
1051-
{
1052-
free(lang_ietf); // Free if not a subtitle track
1053-
lang_ietf = NULL;
1054-
}
10551038
MATROSKA_SWITCH_BREAK(code, code_len);
1056-
10571039
/* Misc ids */
10581040
case MATROSKA_VOID:
10591041
read_vint_block_skip(file);
@@ -1349,22 +1331,19 @@ void parse_segment(struct matroska_ctx *mkv_ctx)
13491331

13501332
char *generate_filename_from_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_track *track)
13511333
{
1352-
// Use lang_ietf if available, otherwise fall back to lang
1353-
const char *lang_to_use = track->lang_ietf ? track->lang_ietf : track->lang;
13541334
const char *basename = get_basename(mkv_ctx->filename);
13551335
const char *extension = matroska_track_text_subtitle_id_extensions[track->codec_id];
1356-
1357-
// Calculate needed size: basename + "_" + lang + "_" + index + "." + extension + null
1358-
size_t needed = strlen(basename) + strlen(lang_to_use) + strlen(extension) + 32;
1336+
/* Prefer the BCP-47 IETF tag (e.g. "zh-Hant") over the legacy
1337+
* ISO-639-2 code (e.g. "chi") when one is available. */
1338+
const char *lang_tag = track->lang_ietf ? track->lang_ietf : track->lang;
1339+
size_t needed = strlen(basename) + strlen(lang_tag) + strlen(extension) + 32;
13591340
char *buf = malloc(needed);
13601341
if (buf == NULL)
13611342
fatal(EXIT_NOT_ENOUGH_MEMORY, "In generate_filename_from_track: Out of memory.");
1362-
13631343
if (track->lang_index == 0)
1364-
snprintf(buf, needed, "%s_%s.%s", basename, lang_to_use, extension);
1344+
snprintf(buf, needed, "%s_%s.%s", basename, lang_tag, extension);
13651345
else
1366-
snprintf(buf, needed, "%s_%s_" LLD ".%s", basename, lang_to_use,
1367-
track->lang_index, extension);
1346+
snprintf(buf, needed, "%s_%s_" LLD ".%s", basename, lang_tag, track->lang_index, extension);
13681347
return buf;
13691348
}
13701349

@@ -1599,17 +1578,18 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
15991578
}
16001579

16011580
// Generate base filename (without extension)
1602-
const char *lang_to_use = track->lang_ietf ? track->lang_ietf : track->lang;
16031581
const char *basename = get_basename(mkv_ctx->filename);
1604-
size_t needed = strlen(basename) + strlen(lang_to_use) + 32;
1582+
/* Prefer the BCP-47 IETF tag over the legacy ISO-639-2 code. */
1583+
const char *lang_tag = track->lang_ietf ? track->lang_ietf : track->lang;
1584+
size_t needed = strlen(basename) + strlen(lang_tag) + 32;
16051585
char *base_filename = malloc(needed);
16061586
if (base_filename == NULL)
16071587
fatal(EXIT_NOT_ENOUGH_MEMORY, "In save_vobsub_track: Out of memory.");
16081588

16091589
if (track->lang_index == 0)
1610-
snprintf(base_filename, needed, "%s_%s", basename, lang_to_use);
1590+
snprintf(base_filename, needed, "%s_%s", basename, lang_tag);
16111591
else
1612-
snprintf(base_filename, needed, "%s_%s_" LLD, basename, lang_to_use, track->lang_index);
1592+
snprintf(base_filename, needed, "%s_%s_" LLD, basename, lang_tag, track->lang_index);
16131593

16141594
// Create .sub filename
16151595
char *sub_filename = malloc(needed + 5);
@@ -1664,7 +1644,7 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
16641644

16651645
// Add language identifier line
16661646
char lang_line[128];
1667-
snprintf(lang_line, sizeof(lang_line), "\nid: %s, index: 0\n", lang_to_use);
1647+
snprintf(lang_line, sizeof(lang_line), "\nid: %s, index: 0\n", track->lang);
16681648
write_wrapped(idx_desc, lang_line, strlen(lang_line));
16691649

16701650
// Buffer for PS/PES headers and padding
@@ -1710,7 +1690,6 @@ static void save_vobsub_track(struct matroska_ctx *mkv_ctx, struct matroska_sub_
17101690
write_wrapped(sub_desc, (char *)zero_buf, padding_needed);
17111691
bytes_written += padding_needed;
17121692
}
1713-
17141693
file_pos += bytes_written;
17151694
}
17161695

@@ -1932,17 +1911,21 @@ void free_sub_track(struct matroska_sub_track *track)
19321911

19331912
void matroska_save_all(struct matroska_ctx *mkv_ctx, char *lang)
19341913
{
1935-
char *match;
19361914
for (int i = 0; i < mkv_ctx->sub_tracks_count; i++)
19371915
{
19381916
if (lang)
19391917
{
1940-
// Try to match against IETF tag first if available
1918+
/* Match against lang_ietf (BCP-47, e.g. "en-US") first,
1919+
* then fall back to lang (ISO-639-2, e.g. "eng").
1920+
* This lets users pass either form to --mkvlang. */
1921+
int matched = 0;
19411922
if (mkv_ctx->sub_tracks[i]->lang_ietf &&
1942-
(match = strstr(lang, mkv_ctx->sub_tracks[i]->lang_ietf)) != NULL)
1943-
save_sub_track(mkv_ctx, mkv_ctx->sub_tracks[i]);
1944-
// Fall back to 3-letter code
1945-
else if ((match = strstr(lang, mkv_ctx->sub_tracks[i]->lang)) != NULL)
1923+
strstr(lang, mkv_ctx->sub_tracks[i]->lang_ietf) != NULL)
1924+
matched = 1;
1925+
if (!matched &&
1926+
strstr(lang, mkv_ctx->sub_tracks[i]->lang) != NULL)
1927+
matched = 1;
1928+
if (matched)
19461929
save_sub_track(mkv_ctx, mkv_ctx->sub_tracks[i]);
19471930
}
19481931
else

0 commit comments

Comments
 (0)