summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-12-05 10:45:52 -0500
committerMatthias Clasen <mclasen@redhat.com>2021-12-05 10:51:24 -0500
commitf5fdfe4e16b7da761d918f40bb82dad52513c9ff (patch)
treef7e3e22790db7532672e73fddabfaa18ffc891c0
parentc1254259233dc9916cf1983d8e51d5441a0ab617 (diff)
downloadpango-tab-crash-fix.tar.gz
Fix a crash in tab handlingtab-crash-fix
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
-rw-r--r--pango/pango-layout.c22
-rw-r--r--tests/layouts/tab-crash.layout1429
-rw-r--r--tests/meson.build1
3 files changed, 1449 insertions, 3 deletions
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 = [