diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md index 9fcfa6163..0735e46d5 100644 --- a/ci/release/changelogs/next.md +++ b/ci/release/changelogs/next.md @@ -18,3 +18,4 @@ - Fixes panic using reserved keywords as containers [#1358](https://github.com/terrastruct/d2/pull/1358) - When multiple classes are applied changing different attributes of arrowheads, they are all applied instead of only the last one [#1362](https://github.com/terrastruct/d2/pull/1362) +- Prevent empty block strings [#1364](https://github.com/terrastruct/d2/pull/1364) diff --git a/d2compiler/compile.go b/d2compiler/compile.go index 8c60316cd..2e85a27be 100644 --- a/d2compiler/compile.go +++ b/d2compiler/compile.go @@ -270,6 +270,9 @@ func (c *compiler) compileLabel(attrs *d2graph.Attributes, f d2ir.Node) { // TODO: Delete instead. attrs.Label.Value = scalar.ScalarString() case *d2ast.BlockString: + if strings.TrimSpace(scalar.ScalarString()) == "" { + c.errorf(f.LastPrimaryKey(), "block string cannot be empty") + } attrs.Language = scalar.Tag fullTag, ok := ShortToFullLanguageAliases[scalar.Tag] if ok { diff --git a/d2compiler/compile_test.go b/d2compiler/compile_test.go index 78dbd5365..3a73a9b08 100644 --- a/d2compiler/compile_test.go +++ b/d2compiler/compile_test.go @@ -610,6 +610,24 @@ x: { expErr: `d2/testdata/d2compiler/TestCompile/md_block_string_err.d2:4:19: unexpected text after md block string. See https://d2lang.com/tour/text#advanced-block-strings. d2/testdata/d2compiler/TestCompile/md_block_string_err.d2:5:1: block string must be terminated with |`, }, + { + name: "no_empty_block_string", + text: `Text: |md |`, + expErr: `d2/testdata/d2compiler/TestCompile/no_empty_block_string.d2:1:1: block string cannot be empty`, + }, + { + name: "no_white_spaces_only_block_string", + text: `Text: |md |`, + expErr: `d2/testdata/d2compiler/TestCompile/no_white_spaces_only_block_string.d2:1:1: block string cannot be empty`, + }, + { + name: "no_new_lines_only_block_string", + text: `Text: |md + + +|`, + expErr: `d2/testdata/d2compiler/TestCompile/no_new_lines_only_block_string.d2:1:1: block string cannot be empty`, + }, { name: "underscore_edge_existing", diff --git a/e2etests/measured_test.go b/e2etests/measured_test.go index 3c33c5c24..777fda482 100644 --- a/e2etests/measured_test.go +++ b/e2etests/measured_test.go @@ -26,14 +26,6 @@ func testMeasured(t *testing.T) { name: "empty-sql_table", mtexts: []*d2target.MText{}, script: `a: "" { shape: sql_table } -`, - }, - { - name: "empty-markdown", - mtexts: []*d2target.MText{}, - script: `a: |md -` + " " + ` -| `, }, } diff --git a/e2etests/regression_test.go b/e2etests/regression_test.go index e0453a15e..be778d758 100644 --- a/e2etests/regression_test.go +++ b/e2etests/regression_test.go @@ -929,19 +929,6 @@ cf many required: { style.stroke-width: 8 } } -`, - }, - { - name: "empty_md_measurement", - script: ` -a -b: |md - - -| -c -d -a -> b -> c `, }, loadFromFile(t, "slow_grid"), diff --git a/testdata/d2compiler/TestCompile/no_empty_block_string.exp.json b/testdata/d2compiler/TestCompile/no_empty_block_string.exp.json new file mode 100644 index 000000000..bf0a8c3a8 --- /dev/null +++ b/testdata/d2compiler/TestCompile/no_empty_block_string.exp.json @@ -0,0 +1,12 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/no_empty_block_string.d2,0:0:0-0:11:11", + "errmsg": "d2/testdata/d2compiler/TestCompile/no_empty_block_string.d2:1:1: block string cannot be empty" + } + ] + } +} diff --git a/testdata/d2compiler/TestCompile/no_empty_block_strings.exp.json b/testdata/d2compiler/TestCompile/no_empty_block_strings.exp.json new file mode 100644 index 000000000..be534202f --- /dev/null +++ b/testdata/d2compiler/TestCompile/no_empty_block_strings.exp.json @@ -0,0 +1,12 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/no_empty_block_strings.d2,0:0:0-0:11:11", + "errmsg": "d2/testdata/d2compiler/TestCompile/no_empty_block_strings.d2:1:1: block string cannot be empty" + } + ] + } +} diff --git a/testdata/d2compiler/TestCompile/no_new_lines_only_block_string.exp.json b/testdata/d2compiler/TestCompile/no_new_lines_only_block_string.exp.json new file mode 100644 index 000000000..2dff86029 --- /dev/null +++ b/testdata/d2compiler/TestCompile/no_new_lines_only_block_string.exp.json @@ -0,0 +1,12 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/no_new_lines_only_block_string.d2,0:0:0-3:1:13", + "errmsg": "d2/testdata/d2compiler/TestCompile/no_new_lines_only_block_string.d2:1:1: block string cannot be empty" + } + ] + } +} diff --git a/testdata/d2compiler/TestCompile/no_white_spaces_only_block_string.exp.json b/testdata/d2compiler/TestCompile/no_white_spaces_only_block_string.exp.json new file mode 100644 index 000000000..ab68a6cc0 --- /dev/null +++ b/testdata/d2compiler/TestCompile/no_white_spaces_only_block_string.exp.json @@ -0,0 +1,12 @@ +{ + "graph": null, + "err": { + "ioerr": null, + "errs": [ + { + "range": "d2/testdata/d2compiler/TestCompile/no_white_spaces_only_block_string.d2,0:0:0-0:16:16", + "errmsg": "d2/testdata/d2compiler/TestCompile/no_white_spaces_only_block_string.d2:1:1: block string cannot be empty" + } + ] + } +}