Skip to content

Commit f0ce956

Browse files
wm4Uoti Urpala
wm4
authored and
Uoti Urpala
committed
subassconvert: handle unquoted attributes in subrip font tags
Previously, mplayer didn't convert tags like <font color=#00FF00>. But such subtitles exist in the wild, and should be handled.
1 parent aadf100 commit f0ce956

File tree

3 files changed

+56
-27
lines changed

3 files changed

+56
-27
lines changed

bstr.c

+8
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,14 @@ struct bstr *bstr_splitlines(void *talloc_ctx, struct bstr str)
185185
return r;
186186
}
187187

188+
bool bstr_eatstart(struct bstr *s, struct bstr prefix)
189+
{
190+
if (!bstr_startswith(*s, prefix))
191+
return false;
192+
*s = bstr_cut(*s, prefix.len);
193+
return true;
194+
}
195+
188196
void bstr_lower(struct bstr str)
189197
{
190198
for (int i = 0; i < str.len; i++)

bstr.h

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ int bstr_decode_utf8(struct bstr str, struct bstr *out_next);
8282
// On error, -1 is returned. On success, it returns a value in the range [1, 4].
8383
int bstr_parse_utf8_code_length(unsigned char b);
8484

85+
// If s starts with prefix, return true and return the rest of the string in s.
86+
bool bstr_eatstart(struct bstr *s, struct bstr prefix);
87+
8588
static inline struct bstr bstr_cut(struct bstr str, int n)
8689
{
8790
if (n > str.len)

sub/subassconvert.c

+45-27
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,27 @@ static const struct {
106106

107107
#define SUBRIP_MAX_STACKED_FONT_TAGS 16
108108

109+
/* Read the attribute value starting at *s, and skip *s past the value.
110+
* Set out_value to the parsed value, with possible '"' stripped.
111+
* Return whether the attribute is well formed. */
112+
static bool read_value(char **s, struct bstr *out_value)
113+
{
114+
char term = 0;
115+
if (**s == '"') {
116+
term = '"';
117+
(*s)++;
118+
}
119+
out_value->start = *s;
120+
out_value->len = 0;
121+
unsigned char *start = *s;
122+
unsigned char *end = term ? strchr(start, term) : strpbrk(start, " >");
123+
if (!end)
124+
return false;
125+
out_value->len = end - out_value->start;
126+
*s = end + (term ? 1 : 0);
127+
return true;
128+
}
129+
109130
void subassconvert_subrip(const char *orig, char *dest, int dest_buffer_size)
110131
{
111132
/* line is not const to avoid warnings with strtol, etc.
@@ -174,34 +195,35 @@ void subassconvert_subrip(const char *orig, char *dest, int dest_buffer_size)
174195
line += 6;
175196

176197
while (*line && *line != '>') {
177-
if (strncmp(line, "size=\"", 6) == 0) {
178-
line += 6;
179-
tag->size = strtol(line, &line, 10);
180-
if (*line != '"')
198+
if (strncmp(line, "size=", 5) == 0) {
199+
line += 5;
200+
struct bstr val;
201+
if (!read_value(&line, &val))
202+
break;
203+
tag->size = bstrtoll(val, &val, 10);
204+
if (val.len)
181205
break;
182206
append_text(&new_line, "{\\fs%d}", tag->size);
183207
tag->has_size = true;
184208
has_valid_attr = true;
185-
} else if (strncmp(line, "color=\"", 7) == 0) {
186-
line += 7;
187-
if (*line == '#') {
209+
} else if (strncmp(line, "color=", 6) == 0) {
210+
line += 6;
211+
struct bstr val;
212+
if (!read_value(&line, &val))
213+
break;
214+
if (bstr_eatstart(&val, bstr("#"))) {
188215
// #RRGGBB format
189-
line++;
190-
tag->color = strtol(line, &line, 16) & 0x00ffffff;
191-
if (*line != '"')
216+
tag->color = bstrtoll(val, &val, 16) & 0x00ffffff;
217+
if (val.len)
192218
break;
193219
tag->color = ((tag->color & 0xff) << 16)
194220
| (tag->color & 0xff00)
195221
| ((tag->color & 0xff0000) >> 16);
196222
} else {
197223
// Standard web colors
198-
int len = indexof(line, '"');
199-
if (len <= 0)
200-
break;
201224
for (int i = 0; i < FF_ARRAY_ELEMS(subrip_web_colors); i++) {
202225
char *color = subrip_web_colors[i].s;
203-
if (strlen(color) == len
204-
&& strncasecmp(line, color, len) == 0) {
226+
if (bstrcasecmp(val, bstr(color)) == 0) {
205227
tag->color = subrip_web_colors[i].v;
206228
goto foundcolor;
207229
}
@@ -211,29 +233,25 @@ void subassconvert_subrip(const char *orig, char *dest, int dest_buffer_size)
211233
mp_tmsg(MSGT_SUBREADER, MSGL_WARN,
212234
"SubRip: unknown font color in subtitle: %s\n", orig);
213235
append_text(&new_line, "{\\c}");
214-
line += len + 1;
215236
continue;
216237

217-
foundcolor:
218-
line += len;
238+
foundcolor: ;
219239
}
220240
append_text(&new_line, "{\\c&H%06X&}", tag->color);
221241
tag->has_color = true;
222242
has_valid_attr = true;
223-
} else if (strncmp(line, "face=\"", 6) == 0) {
243+
} else if (strncmp(line, "face=", 5) == 0) {
224244
/* Font face attribute */
225-
line += 6;
226-
int len = indexof(line, '"');
227-
if (len <= 0)
245+
line += 5;
246+
struct bstr val;
247+
if (!read_value(&line, &val))
228248
break;
229-
tag->face.start = line;
230-
tag->face.len = len;
231-
line += len;
249+
tag->face = val;
232250
append_text(&new_line, "{\\fn%.*s}", BSTR_P(tag->face));
233251
tag->has_face = true;
234252
has_valid_attr = true;
235-
}
236-
line++;
253+
} else
254+
line++;
237255
}
238256

239257
if (!has_valid_attr || *line != '>') { /* Not valid font tag */

0 commit comments

Comments
 (0)