Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save tassa-yoniso-manasi-karoto/b93236d1fd0310de6074e449e670de17 to your computer and use it in GitHub Desktop.

Select an option

Save tassa-yoniso-manasi-karoto/b93236d1fd0310de6074e449e670de17 to your computer and use it in GitHub Desktop.

Summary

The alphabetical order from go-astisub is INVALID and is the cause of the "bad int field" error. Aegisub parses style fields by fixed position, completely ignoring the Format line.


Detailed Findings

1. Is there an official/standard order for V4+ Style format fields?

YES. The canonical V4+ Styles Format line is:

Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding

Source: Aegisub-master/src/subtitle_format_ass.cpp (lines 55-56):

if (group == AssEntryGroup::STYLE)
    return "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" LINEBREAK;

Note: The written specification (ssa_v4_plus_specs.txt lines 463-466) lists a slightly different set with TertiaryColour and AlphaLevel:

Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding

The Effective Standard (per reference implementation) uses OutlineColour instead of TertiaryColour and omits AlphaLevel entirely (line 599 of spec confirms: "Field 17: Not present in ASS.").


2. Must parsers follow the Format line order, or do they expect a fixed order?

Contradiction between specification and implementation:

Written Specification (lines 469-471) states:

"The format line allows new fields to be added to the script format in future, and yet allow old versions of the software to read the fields it recognises - even if the field order is changed."

Reference Implementation (Aegisub) ignores this and parses by fixed position.

From Aegisub-master/src/ass_style.cpp (lines 106-175), the parser is purely positional:

AssStyle::AssStyle(std::string_view str, int version) {
    parser p(str);

    name = p.next_str();      // Position 1
    font = p.next_str();      // Position 2
    fontsize = p.next_double(); // Position 3

    if (version != 0) {
        primary = p.next_color();   // Position 4
        secondary = p.next_color(); // Position 5
        outline = p.next_color();   // Position 6
        shadow = p.next_color();    // Position 7
    }
    // ... continues in fixed order
    bold = !!p.next_int();    // Position 8
    italic = !!p.next_int();  // Position 9
    // etc.

The parser has no code to read the Format line and map fields by name. It simply iterates through comma-separated values in order.


3. Is the alphabetical order causing the "bad int field" error?

YES, absolutely. Here is exactly why:

When go-astisub writes:

Format: Name, Alignment, Angle, BackColour, Bold, BorderStyle, ...
Style: Default,2,0.00,&H80000000,-1,1,...

Aegisub's parser expects:

  • Position 1: Name (string) -- gets Default OK
  • Position 2: Fontname (string) -- gets 2 (the Alignment value) -- still OK (any string works)
  • Position 3: Fontsize (double) -- gets 0.00 (the Angle value) -- OK
  • Position 4: PrimaryColour (color) -- gets &H80000000 (the BackColour) -- might work
  • Position 5: SecondaryColour (color) -- gets -1 (the Bold flag) -- fails or corrupts
  • Position 6-7: Colors expecting &HAABBGGRR format...
  • Position 8: Bold (int) -- gets something that should be a color string -- throws "bad int field"

The error is thrown in Aegisub-master/src/ass_style.cpp (lines 81-87):

int next_int() {
    try {
        return boost::lexical_cast<int>(next_tok());
    }
    catch (boost::bad_lexical_cast const&) {
        throw SubtitleFormatParseError("Malformed style: bad int field");
    }
}

Conclusion

Aspect Specification Says Implementation Does
Format line purpose Defines field order Ignored during parsing
Field order Can be changed Must be fixed/canonical
Parser behavior Map by field name Parse by position

Effective Standard: The go-astisub library MUST use the exact field order from the reference implementation. The alphabetical ordering is non-compliant and will break compatibility with Aegisub and likely most other ASS-compatible software (libass, VSFilter, etc.) that follow Aegisub's conventions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment