Skip to content

Commit 6a877c9

Browse files
authored
Merge pull request #833 from sphinx-contrib/provide-cdata-quirk
cdata workaround for confluence 8.0.x to 8.2.x
2 parents 936e7be + dcb35b2 commit 6a877c9

File tree

5 files changed

+53
-1
lines changed

5 files changed

+53
-1
lines changed

CHANGES.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Development
66
* Fixed re-publishing issues when certain options change (e.g. parent page)
77
* Improve support when using the sphinxcontrib-video extension
88
* Introduce the ``confluence_permit_raw_html`` option
9+
* Provide quirk for CDATA issues on Confluence 8.0.x to 8.2.x
910
* Support configuring the theme on generated code block macros
1011
* Support page-specific editor and full-width overrides
1112
* Support page-specific parent identifier overrides when publishing

sphinxcontrib/confluencebuilder/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ def setup(app):
245245
cm.add_conf('confluence_adv_node_handler')
246246
# Permit any string value to be provided as the editor.
247247
cm.add_conf('confluence_adv_permit_editor', 'confluence')
248+
# Flag to tweak code-block CDATA EOFs to prevent publishing issues.
249+
cm.add_conf_bool('confluence_adv_quirk_cdata')
248250
# List of optional features/macros/etc. restricted for use.
249251
cm.add_conf('confluence_adv_restricted', 'confluence')
250252
# Enablement of tracing processed data.

sphinxcontrib/confluencebuilder/exceptions.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,35 @@ def __init__(self, server_url):
263263
'''.format(url=server_url))
264264

265265

266+
class ConfluenceUnexpectedCdataError(ConfluenceError):
267+
def __init__(self):
268+
super().__init__('''
269+
---
270+
Unexpected Confluence XML stream CDATA parsing error
271+
272+
Confluence has reported an error processing a document which contains
273+
CDATA data (e.g. a code block using `<![CDATA[data]]>`). This is
274+
unexpected since the data should be properly formed. There is a high
275+
chance that this is occurring on a Confluence instance which introduced
276+
some processing logic that incorrectly breaks the parsing of CDATA EOF
277+
strings (as of Confluence 8.x). This should be addressed in Confluence
278+
8.3.0 (or newer) release [1].
279+
280+
To workaround this issue for the configured Confluence instance, a user
281+
can enable the `confluence_adv_quirk_cdata` inside their `conf.py`
282+
configuration file. For example:
283+
284+
confluence_adv_quirk_cdata = True
285+
286+
If enabling this option does not resolve the publication issue, then
287+
this error message does not apply. Feel free to report this issue noting
288+
the exception message above this message.
289+
290+
[1]: https://jira.atlassian.com/browse/CONFSERVER-82849
291+
---
292+
''')
293+
294+
266295
class ConfluenceUnreconciledPageError(ConfluenceError):
267296
def __init__(self, page_name, page_id, url, ex):
268297
super().__init__('''

sphinxcontrib/confluencebuilder/publisher.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
from sphinxcontrib.confluencebuilder.exceptions import ConfluencePermissionError
1717
from sphinxcontrib.confluencebuilder.exceptions import ConfluencePublishAncestorError
1818
from sphinxcontrib.confluencebuilder.exceptions import ConfluencePublishSelfAncestorError
19+
from sphinxcontrib.confluencebuilder.exceptions import ConfluenceUnexpectedCdataError
1920
from sphinxcontrib.confluencebuilder.exceptions import ConfluenceUnreconciledPageError
2021
from sphinxcontrib.confluencebuilder.logger import ConfluenceLogger as logger
2122
from sphinxcontrib.confluencebuilder.rest import Rest
@@ -922,6 +923,9 @@ def store_page(self, page_name, data, parent_id=None):
922923
self.rest_client.post(url, labels)
923924

924925
except ConfluenceBadApiError as ex:
926+
if str(ex).find('CDATA block has embedded') != -1:
927+
raise ConfluenceUnexpectedCdataError from ex
928+
925929
# Check if Confluence reports that the new page request
926930
# fails, indicating it already exists. This is usually
927931
# (outside of possible permission use cases) that the page
@@ -1235,6 +1239,8 @@ def _update_page(self, page, page_name, data, parent_id=None):
12351239
try:
12361240
self.rest_client.put('content', page_id_explicit, update_page)
12371241
except ConfluenceBadApiError as ex:
1242+
if str(ex).find('CDATA block has embedded') != -1:
1243+
raise ConfluenceUnexpectedCdataError from ex
12381244

12391245
# Handle select API failures by waiting a moment and retrying the
12401246
# content request. If it happens again, the put request will fail as

sphinxcontrib/confluencebuilder/storage/translator.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3613,5 +3613,19 @@ def _escape_cdata(self, data):
36133613
Returns:
36143614
the escaped text
36153615
"""
3616-
data = data.replace(']]>', ']]]]><![CDATA[>')
3616+
3617+
# workaround for Confluence 8.0.x to 8.2.x series
3618+
# (https://jira.atlassian.com/browse/CONFSERVER-82849)
3619+
#
3620+
# The else case here should be always working; however, in some
3621+
# Confluence instances, there was a window where pages could not
3622+
# be uploaded since Confluence would refuse the EOF sequence for
3623+
# CDATA blocks. This workaround can help a user get their content
3624+
# published at the unfortunate tweak of changing any trailing EOF
3625+
# CDATA blocks to have a space character included.
3626+
if self.builder.config.confluence_adv_quirk_cdata:
3627+
data = data.replace(']]>', ']] >')
3628+
else:
3629+
data = data.replace(']]>', ']]]]><![CDATA[>')
3630+
36173631
return ConfluenceBaseTranslator.encode(self, data)

0 commit comments

Comments
 (0)