Edgewall Software
Modify

Opened 3 years ago

Closed 3 years ago

Last modified 3 years ago

#13355 closed defect (fixed)

incomplete inline markup within table cell generates malformed html

Reported by: Jun Omae Owned by: Hong Choi <nik@…>
Priority: normal Milestone: 1.4.3
Component: wiki system Version:
Severity: normal Keywords:
Cc: Branch:
Release Notes:

Fixed malformed html generated from unbalanced inline markups within table cell.

API Changes:
Internal Changes:

Description (last modified by Jun Omae)

(originally reported at th:#13959)

>>> import trac
>>> trac.__version__
'1.4.2'
>>> from trac.mimeview.api import RenderingContext
>>> from trac.resource import Resource
>>> from trac.test import EnvironmentStub
>>> from trac.test import MockRequest
>>> from trac.wiki.formatter import Formatter, format_to_html
>>> resource = Resource('wiki', 'WikiStart')
>>> env = EnvironmentStub()
>>> req = MockRequest(env)
>>> context = RenderingContext(resource, req.href, req.perm)
>>> context.req = req
>>> print(format_to_html(env, context, '|| text^1 ||'))
<table class="wiki">
<tr><td> text<sup>1
</td></tr></table>
</sup>
>>> print(format_to_html(env, context, '|| text^1^ ||'))
<table class="wiki">
<tr><td> text<sup>1</sup>
</td></tr></table>

>>> print(format_to_html(env, context, '|| text**1 ||'))
<table class="wiki">
<tr><td> text<strong>1
</td></tr></table>
</strong>
>>> print(format_to_html(env, context, '|| text**1** ||'))
<table class="wiki">
<tr><td> text<strong>1</strong>
</td></tr></table>

>>>

Complex patterns:

>>> print(format_to_html(env, context, '|| aaa**1 || bbb//2 || ccc^3 ||'))
<table class="wiki">
<tr><td> aaa<strong>1 </td><td> bbb<em>2 </td><td> ccc<sup>3
</td></tr></table>
</sup></em></strong>
>>> print(format_to_html(env, context, '|| aaa**1//2^3,,4~~5 ||'))
<table class="wiki">
<tr><td> aaa<strong>1<em>2<sup>3<sub>4<del>5
</td></tr></table>
</del></sub></sup></em></strong>

Attachments (4)

incomplete_inline_markup_within_table_cell_generates_malformed_html_patch_suggestion_v01 (767 bytes ) - added by Hong Choi <nik@…> 3 years ago.
broken-syntax-within-table_patch-v02.diff (1.4 KB ) - added by Hong Choi <nik@…> 3 years ago.
broken-syntax-within-table_patch-v03.diff (1.9 KB ) - added by Hong Choi <nik@…> 3 years ago.
force to close broken wiki text decoration tokens
broken-syntax-within-table_patch-v04.diff (2.5 KB ) - added by Hong Choi <nik@…> 3 years ago.
Close tags in reversed way. Testcases for multiple token cases are added

Download all attachments as: .zip

Change History (16)

comment:1 by anonymous, 3 years ago

Hello. I've just attached a patch file for this ticket.

Maybe the right way to fix this problem is adding some warning messages to user about those wrong markup tokens. But I'm not sure trac has warning mechanism for this case. So, the method I fix this issue is just resetting formatter's internal states, which means omitting close tags. Of course the formatter can insert close tags, if someone says it's the 'right' way. :)

Please review and give me some feedback.

comment:2 by Jun Omae, 3 years ago

Thanks for the patch! I haven't test it but it seems that makes sense.

  • Did you run unit and functional tests and confirm they pass?
  • Could you please try to add unit tests for this issue.

See TracDev/SubmittingPatches and TracDev/UnitTests.

p.s. the attached file name is long a little. I think it would be good to be short and simple, and the suffix be *.diff or *.patch.

Last edited 3 years ago by Jun Omae (previous) (diff)

by Hong Choi <nik@…>, 3 years ago

comment:3 by Hong Choi <nik@…>, 3 years ago

Aha! I got it.

  • Filename : shorten with .diff suffix
  • Testcase : added very basic broken syntax test
  • Tests : all passed. 3 were skipped by default.

comment:4 by Jun Omae, 3 years ago

Description: modified (diff)

Thanks. However, I'd like to put </sup> before </td> in this case. Missing </sup> in your suggested changes.

by Hong Choi <nik@…>, 3 years ago

force to close broken wiki text decoration tokens

comment:5 by Hong Choi <nik@…>, 3 years ago

Sure. If you say so. :)

And, I realize that the same patch should be applied on cell closing. For example, || a^1 || b^2 || should be parsed as a<sup>1</sup> and b<sup>2</sup>, not as a<sup>1 and b</sup>2. I added another test case for that.

comment:6 by Jun Omae, 3 years ago

trac/wiki/formatter.py

--- trac/wiki/formatter.py (revision 17500)
+++ trac/wiki/formatter.py (working copy)
@@ -1092,7 +1092,10 @@
             attrs += ' style="text-align: %s"' % textalign
         td = '<%s%s>' % (cell, attrs)
         if self.in_table_cell:
-            td = '</%s>' % self.in_table_cell + td
+            unclosed = ''
+            for tag in self._open_tags:
+                    unclosed += self.close_tag(tag)
+            td = unclosed + '</%s>' % self.in_table_cell + td
         self.in_table_cell = cell
         return td
 
  • self._open_tags should be used from the last entry.
    • refs. def flush_tags()
  • self._open_tags should be clear after closing the tags.
  • The indent should be 4 spaces
@@ -1126,6 +1129,8 @@
         if self.in_table_row and (not self.continue_table_row or force):
             self.in_table_row = 0
             if self.in_table_cell:
+                for tag in self._open_tags:
+                    self.out.write(self.close_tag(tag))
                 self.out.write('</%s>' % self.in_table_cell)
                 self.in_table_cell = ''
             self.out.write('</tr>')
  • self.flush_tags() may be used here.

trac/wiki/tests/wiki-tests.txt

  • Should add test with multiple markups:
    • e.g. || aaa^1**2 || bbb**1//2^3 ||
  • Should add test which table cell doesn't end with ||
    • e.g. || aaa^1**2 || bbb**1//2^3

by Hong Choi <nik@…>, 3 years ago

Close tags in reversed way. Testcases for multiple token cases are added

in reply to:  6 ; comment:7 by Hong Choi <nik@…>, 3 years ago

trac/wiki/formatter.py

  • self._open_tags should be used from the last entry.
    • Sure!
  • self._open_tags should be clear after closing the tags.
    • I don't think so. close_tag() handles everything.
  • The indent should be 4 spaces
    • My mistake, corrected.
  • self.flush_tags() may be used here.
    • close_tags() will take care of those things.

trac/wiki/tests/wiki-tests.txt

  • Should add test with multiple markups
    • Added and passed.
  • Should add test which table cell doesn't end with ||
    • Also added and passed.

Please let me know any further details! :)

in reply to:  7 comment:8 by Jun Omae, 3 years ago

Owner: set to Jun Omae
Status: newassigned
  • self._open_tags should be clear after closing the tags.
    • I don't think so. close_tag() handles everything.

_open_tags shouldn't be changed during iteration of _open_tags (by close_tag() in this case).

  • self.flush_tags() may be used here.
    • close_tags() will take care of those things.

We shouldn't put different logic to get the same result by flush_tags().


Revised and cleaned up the changes. I'm going to push it. Thanks.

comment:9 by Jun Omae, 3 years ago

Milestone: next-stable-1.4.x1.4.3

comment:10 by Ryan J Ollos, 3 years ago

The latest revisions by Jun look good. Thank you for the contribution Hong Choi!

One tiny thing, I wonder if this would be simpler and more consistent with other code in module:

  • trac/wiki/formatter.py

    diff --git a/trac/wiki/formatter.py b/trac/wiki/formatter.py
    index ecf108b24b..d9f1a5608e 100644
    a b class Formatter(object):  
    10981098        if self.in_table_cell:
    10991099            close_tags = ''.join(self._get_close_tag(tag)
    11001100                                 for tag in self.pop_tags())
    1101             td = close_tags + '</%s>' % self.in_table_cell + td
     1101            td = '%s</%s>%s' % (close_tags, self.in_table_cell, td)
    11021102        self.in_table_cell = cell
    11031103        return td

comment:11 by Jun Omae, 3 years ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Your suggestion makes sense. Thanks.

Pushed the changes with the suggestion in [17510] and merged in [17511].

comment:12 by Jun Omae, 3 years ago

Owner: changed from Jun Omae to Hong Choi <nik@…>

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Hong Choi <nik@…>.
The resolution will be deleted. Next status will be 'reopened'.
to The owner will be changed from Hong Choi <nik@…> to the specified user.

Add Comment


E-mail address and name can be saved in the Preferences .
 
Note: See TracTickets for help on using tickets.