@@ -68,6 +68,9 @@ func TestHTML2BlockDOMQuotedFontFamily(t *testing.T) {
6868 styled , bold , link := 0 , false , false
6969 ast .Walk (engine .BlockDOM2Tree (response .Data ).Root , func (n * ast.Node , entering bool ) ast.WalkStatus {
7070 if entering && n .Type == ast .NodeTextMark {
71+ if strings .TrimSpace (n .TextMarkTextContent ) == "" {
72+ return ast .WalkContinue
73+ }
7174 style := n .IALAttr ("style" )
7275 for _ , want := range []string {`font-family: "Mona Sans VF", "Segoe UI", Arial;` , "color: rgb(31, 35, 40);" , "background-color: white;" , "font-size: 14.000000px;" } {
7376 if ! strings .Contains (style , want ) {
@@ -124,3 +127,42 @@ func TestHTML2BlockDOMMatchesElementsByDefault(t *testing.T) {
124127 t .Fatalf ("source appearance survived: %s" , response .Data )
125128 }
126129}
130+
131+ func TestHTML2BlockDOMDoesNotLeakWhitespaceTextMarkStyles (t * testing.T ) {
132+ originalConf := model .Conf
133+ model .Conf = model .NewAppConf ()
134+ model .Conf .System = & conf.System {}
135+ t .Cleanup (func () { model .Conf = originalConf })
136+ gin .SetMode (gin .TestMode )
137+ input := `<h3 style="color: rgb(31, 35, 40); font-family: Arial; font-size: 20px; font-weight: 600">` +
138+ `author<span> </span>commented<span> </span><relative-time><span>now</span></relative-time></h3>`
139+ body , err := json .Marshal (map [string ]any {
140+ "dom" : input , "skipBase64Assets" : true , "skipInlineSVGAssets" : true , "preserveSourceFormat" : true ,
141+ })
142+ if err != nil {
143+ t .Fatal (err )
144+ }
145+ recorder := httptest .NewRecorder ()
146+ context , _ := gin .CreateTestContext (recorder )
147+ context .Request = httptest .NewRequest (http .MethodPost , "/api/lute/html2BlockDOM" , strings .NewReader (string (body )))
148+ context .Request .Header .Set ("Content-Type" , "application/json" )
149+ html2BlockDOM (context )
150+ var response struct {
151+ Code int
152+ Data string
153+ }
154+ if err = json .Unmarshal (recorder .Body .Bytes (), & response ); err != nil || response .Code != 0 {
155+ t .Fatalf ("conversion failed: %s, %v" , recorder .Body .String (), err )
156+ }
157+ if strings .Contains (response .Data , "{: style=" ) {
158+ t .Fatalf ("leaked attributes: %s" , response .Data )
159+ }
160+ if ! strings .Contains (response .Data , `style="color: rgb(31, 35, 40);font-family: Arial;font-size: 20.000000px;"` ) {
161+ t .Fatalf ("lost visible source formatting: %s" , response .Data )
162+ }
163+ for _ , text := range []string {"author" , "commented" , "now" } {
164+ if ! strings .Contains (response .Data , text ) {
165+ t .Fatalf ("lost %q: %s" , text , response .Data )
166+ }
167+ }
168+ }
0 commit comments