From f5fdfe4e16b7da761d918f40bb82dad52513c9ff Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 5 Dec 2021 10:45:52 -0500 Subject: Fix a crash in tab handling When we uninsert the current tab run, we need to reset our tab state to prevent last_tab->glyphs to become a dangling pointer. Test included. Fixes: #634 --- pango/pango-layout.c | 22 +- tests/layouts/tab-crash.layout | 1429 ++++++++++++++++++++++++++++++++++++++++ tests/meson.build | 1 + 3 files changed, 1449 insertions(+), 3 deletions(-) create mode 100644 tests/layouts/tab-crash.layout diff --git a/pango/pango-layout.c b/pango/pango-layout.c index 060420a8..ed46d57a 100644 --- a/pango/pango-layout.c +++ b/pango/pango-layout.c @@ -3775,6 +3775,7 @@ insert_run (PangoLayoutLine *line, if (state->last_tab.glyphs && run->glyphs != state->last_tab.glyphs) { gboolean found_decimal = FALSE; + int width; /* Adjust the tab position so placing further runs will continue to * maintain the tab placement. In the case of decimal tabs, we are @@ -3794,9 +3795,10 @@ insert_run (PangoLayoutLine *line, state->last_tab.width += width; } - state->last_tab.glyphs->glyphs[0].geometry.width = MAX (state->last_tab.pos - state->last_tab.width, 0); + width = MAX (state->last_tab.pos - state->last_tab.width, 0); + state->last_tab.glyphs->glyphs[0].geometry.width = width; - if (found_decimal) + if (found_decimal || width == 0) state->last_tab.glyphs = NULL; } } @@ -4494,7 +4496,21 @@ process_line (PangoLayout *layout, case BREAK_NONE_FIT: /* Back up over unused runs to run where there is a break */ while (line->runs && line->runs != break_link) - state->items = g_list_prepend (state->items, uninsert_run (line)); + { + PangoLayoutRun *run = line->runs->data; + + /* If we uninsert the current tab run, + * we need to reset the tab state + */ + if (run->glyphs == state->last_tab.glyphs) + { + state->last_tab.glyphs = NULL; + state->last_tab.index = 0; + state->last_tab.align = PANGO_TAB_LEFT; + } + + state->items = g_list_prepend (state->items, uninsert_run (line)); + } state->start_offset = break_start_offset; state->remaining_width = break_remaining_width; diff --git a/tests/layouts/tab-crash.layout b/tests/layouts/tab-crash.layout new file mode 100644 index 00000000..a0e83f5d --- /dev/null +++ b/tests/layouts/tab-crash.layout @@ -0,0 +1,1429 @@ +{ + "context" : { + "font" : "Monospace 12", + "language" : "en-us", + "base-gravity" : "south", + "gravity-hint" : "natural", + "base-dir" : "ltr", + "round-glyph-positions" : true, + "transform" : [ + 1, + 0, + 0, + 1, + 0, + 0 + ] + }, + "comment" : "Reproducer for #634, crash when the tab run gets uninserted", + "text" : "id=3 UNION ALL SELECT NULL, NULL, CONCAT(0x7373737373, 0x73323173656374657374), NULL--\t\t\t\t-->(MYSQL)", + "attributes" : [ + { + "end" : 101, + "type" : "font-desc", + "value" : "Monospace 12" + } + ], + "tabs" : { + "positions-in-pixels" : true, + "positions" : [ + { + "position" : 80, + "alignment" : "left", + "decimal-point" : 0 + } + ] + }, + "width" : 587776, + "output" : { + "is-wrapped" : true, + "is-ellipsized" : false, + "unknown-glyphs" : 0, + "width" : 585728, + "height" : 585728, + "log-attrs" : [ + { + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "sentence-boundary" : true, + "sentence-start" : true, + "backspace-deletes-character" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "word-end" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "word-end" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "word-end" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "word-end" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "expandable-space" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "backspace-deletes-character" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "backspace-deletes-character" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "white" : true, + "cursor-position" : true, + "backspace-deletes-character" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "backspace-deletes-character" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "char-break" : true, + "cursor-position" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-start" : true, + "word-boundary" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "break-inserts-hyphen" : true + }, + { + "char-break" : true, + "cursor-position" : true, + "word-end" : true, + "word-boundary" : true + }, + { + "line-break" : true, + "mandatory-break" : true, + "char-break" : true, + "white" : true, + "cursor-position" : true, + "sentence-boundary" : true, + "sentence-end" : true, + "word-boundary" : true + } + ], + "lines" : [ + { + "start-index" : 0, + "length" : 55, + "paragraph-start" : true, + "direction" : "ltr", + "runs" : [ + { + "offset" : 0, + "length" : 55, + "text" : "id=3 UNION ALL SELECT NULL, NULL, CONCAT(0x7373737373, ", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 76, + "width" : 4096, + "is-cluster-start" : true, + "log-cluster" : 0 + }, + { + "glyph" : 71, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 1 + }, + { + "glyph" : 32, + "width" : 13312, + "is-cluster-start" : true, + "log-cluster" : 2 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 3 + }, + { + "glyph" : 3, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 4 + }, + { + "glyph" : 56, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 5 + }, + { + "glyph" : 49, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 6 + }, + { + "glyph" : 44, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 7 + }, + { + "glyph" : 50, + "width" : 13312, + "is-cluster-start" : true, + "log-cluster" : 8 + }, + { + "glyph" : 49, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 9 + }, + { + "glyph" : 3, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 10 + }, + { + "glyph" : 36, + "width" : 11264, + "is-cluster-start" : true, + "log-cluster" : 11 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 12 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 13 + }, + { + "glyph" : 3, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 14 + }, + { + "glyph" : 54, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 15 + }, + { + "glyph" : 40, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 16 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 17 + }, + { + "glyph" : 40, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 18 + }, + { + "glyph" : 38, + "width" : 11264, + "is-cluster-start" : true, + "log-cluster" : 19 + }, + { + "glyph" : 55, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 20 + }, + { + "glyph" : 3, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 21 + }, + { + "glyph" : 49, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 22 + }, + { + "glyph" : 56, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 23 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 24 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 25 + }, + { + "glyph" : 15, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 26 + }, + { + "glyph" : 3, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 27 + }, + { + "glyph" : 49, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 28 + }, + { + "glyph" : 56, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 29 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 30 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 31 + }, + { + "glyph" : 15, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 32 + }, + { + "glyph" : 3, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 33 + }, + { + "glyph" : 38, + "width" : 11264, + "is-cluster-start" : true, + "log-cluster" : 34 + }, + { + "glyph" : 50, + "width" : 13312, + "is-cluster-start" : true, + "log-cluster" : 35 + }, + { + "glyph" : 49, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 36 + }, + { + "glyph" : 38, + "width" : 11264, + "is-cluster-start" : true, + "log-cluster" : 37 + }, + { + "glyph" : 36, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 38 + }, + { + "glyph" : 55, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 39 + }, + { + "glyph" : 11, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 40 + }, + { + "glyph" : 19, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 41 + }, + { + "glyph" : 91, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 42 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 43 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 44 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 45 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 46 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 47 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 48 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 49 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 50 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 51 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 52 + }, + { + "glyph" : 15, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 53 + }, + { + "glyph" : 268435455, + "width" : 0, + "is-cluster-start" : true, + "log-cluster" : 54 + } + ] + } + ] + }, + { + "start-index" : 55, + "length" : 37, + "paragraph-start" : false, + "direction" : "ltr", + "runs" : [ + { + "offset" : 55, + "length" : 31, + "text" : "0x73323173656374657374), NULL--", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 19, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 0 + }, + { + "glyph" : 91, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 1 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 2 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 3 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 4 + }, + { + "glyph" : 21, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 5 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 6 + }, + { + "glyph" : 20, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 7 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 8 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 9 + }, + { + "glyph" : 25, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 10 + }, + { + "glyph" : 24, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 11 + }, + { + "glyph" : 25, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 12 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 13 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 14 + }, + { + "glyph" : 23, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 15 + }, + { + "glyph" : 25, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 16 + }, + { + "glyph" : 24, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 17 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 18 + }, + { + "glyph" : 22, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 19 + }, + { + "glyph" : 26, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 20 + }, + { + "glyph" : 23, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 21 + }, + { + "glyph" : 12, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 22 + }, + { + "glyph" : 15, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 23 + }, + { + "glyph" : 3, + "width" : 5120, + "is-cluster-start" : true, + "log-cluster" : 24 + }, + { + "glyph" : 49, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 25 + }, + { + "glyph" : 56, + "width" : 12288, + "is-cluster-start" : true, + "log-cluster" : 26 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 27 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 28 + }, + { + "glyph" : 16, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 29 + }, + { + "glyph" : 16, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 30 + } + ] + }, + { + "offset" : 86, + "length" : 1, + "text" : "\t", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 268435455, + "width" : 31744, + "is-cluster-start" : true, + "log-cluster" : 0 + } + ] + }, + { + "offset" : 87, + "length" : 1, + "text" : "\t", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 268435455, + "width" : 81920, + "is-cluster-start" : true, + "log-cluster" : 0 + } + ] + }, + { + "offset" : 88, + "length" : 1, + "text" : "\t", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 268435455, + "width" : 81920, + "is-cluster-start" : true, + "log-cluster" : 0 + } + ] + }, + { + "offset" : 89, + "length" : 1, + "text" : "\t", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 268435455, + "width" : 81920, + "is-cluster-start" : true, + "log-cluster" : 0 + } + ] + }, + { + "offset" : 90, + "length" : 2, + "text" : "--", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 16, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 0 + }, + { + "glyph" : 16, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 1 + } + ] + } + ] + }, + { + "start-index" : 92, + "length" : 8, + "paragraph-start" : false, + "direction" : "ltr", + "runs" : [ + { + "offset" : 92, + "length" : 8, + "text" : ">(MYSQL)", + "bidi-level" : 0, + "gravity" : "south", + "language" : "en-us", + "script" : "latin", + "font" : { + "description" : "DejaVu Sans 12", + "checksum" : "69ccd07023a72ceb27a5e5c22f728627353b60a198170f5e58dd7014221abf01", + "matrix" : [ + 1, + -0, + -0, + 1, + 0, + 0 + ] + }, + "flags" : 0, + "y-offset" : 0, + "start-x-offset" : 0, + "end-x-offset" : 0, + "glyphs" : [ + { + "glyph" : 33, + "width" : 13312, + "is-cluster-start" : true, + "log-cluster" : 0 + }, + { + "glyph" : 11, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 1 + }, + { + "glyph" : 48, + "width" : 14336, + "is-cluster-start" : true, + "log-cluster" : 2 + }, + { + "glyph" : 60, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 3 + }, + { + "glyph" : 54, + "width" : 10240, + "is-cluster-start" : true, + "log-cluster" : 4 + }, + { + "glyph" : 52, + "width" : 13312, + "is-cluster-start" : true, + "log-cluster" : 5 + }, + { + "glyph" : 47, + "width" : 9216, + "is-cluster-start" : true, + "log-cluster" : 6 + }, + { + "glyph" : 12, + "width" : 6144, + "is-cluster-start" : true, + "log-cluster" : 7 + } + ] + } + ] + } + ] + } +} diff --git a/tests/meson.build b/tests/meson.build index 2658f0a2..2acf0def 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -118,6 +118,7 @@ installed_test_layouts_data = [ 'layouts/valid-20.layout', 'layouts/valid-21.layout', 'layouts/valid-22.layout', + 'layouts/tab-crash.layout', ] test_markups_data = [ -- cgit v1.2.1