Subramanya Sastry has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/394242 )
Change subject: Fix crasher in section <-> template conflict resolution code
......................................................................
Fix crasher in section <-> template conflict resolution code
* In some scenarios, a section overlaps transclusion content
partially where it starts somewhere after the start and
goes all the way the end and extends beyond the transclusion
boundary. This is better understood with the example below.
<div>
a
{{1x|
b
==h2==
c
}}
d
</div>
* In this context, in the conflict resolution code,
tplInfo.firstSection will be undefined and was causing a crasher.
This scenario needs to be handled identically to the case
where s1 is an ancestor of s2.
* Added a new test case to cover this scenario.
Change-Id: I1fd22c781f3a37ae5fe91a643faee5287b2c0ada
---
M lib/wt2html/pp/processors/wrapSections.js
M tests/parserTests.txt
2 files changed, 55 insertions(+), 11 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/services/parsoid
refs/changes/42/394242/1
diff --git a/lib/wt2html/pp/processors/wrapSections.js
b/lib/wt2html/pp/processors/wrapSections.js
index 829e4a5..7544779 100644
--- a/lib/wt2html/pp/processors/wrapSections.js
+++ b/lib/wt2html/pp/processors/wrapSections.js
@@ -23,6 +23,9 @@
container: state.doc.createElement('section'),
};
+ // console.log("NEW section @ " + node.nodeName + "; level: "
+ // + newLevel + "; pseudo: " + pseudoSection + "; id: "+
section.debug_id);
+
/* Step 1. Get section stack to the right nesting level
* 1a. Pop stack till we have a higher-level section.
*/
@@ -195,27 +198,31 @@
function resolveTemplateSectionConflicts(state) {
state.templatesToExamine.forEach(function(tplInfo) {
- var s1 = tplInfo.firstSection.container;
- var s2 = tplInfo.lastSection.container;
+ var s1 = tplInfo.firstSection &&
tplInfo.firstSection.container; // could be undefined
+ var s2 = tplInfo.lastSection.container; // guaranteed to be
non-null
// Find a common ancestor of s1 and s2 (could be s1)
var s2Ancestors = arrayMap(DU.pathToRoot(s2));
var s1Ancestors = [];
var ancestor;
var i;
- for (ancestor = s1; !s2Ancestors.has(ancestor); ancestor =
ancestor.parentNode) {
+ if (s1) {
+ for (ancestor = s1; !s2Ancestors.has(ancestor);
ancestor = ancestor.parentNode) {
+ s1Ancestors.push(ancestor);
+ }
+ // ancestor is now the common ancestor of s1 and s2
s1Ancestors.push(ancestor);
+ i = s2Ancestors.get(ancestor);
}
- // ancestor is now the common ancestor of s1 and s2
- s1Ancestors.push(ancestor);
- i = s2Ancestors.get(ancestor);
var n, tplDsr, dmw;
- if (ancestor === s1) {
- // Scenario 1: s1 is s2's ancestor
- s2 = tplInfo.lastSection.container;
+ if (!s1 || ancestor === s1) {
+ // Scenario 1: s1 is s2's ancestor OR s1 doesn't exist.
+ // In either case, s2 only covers part of the
transcluded content.
+ // But, s2 could also include content that follows the
transclusion.
+ // If so, append the content of the section after the
last node
+ // to data-mw.parts.
if (tplInfo.last.nextSibling) {
- // Append the content of the section after the
last node to data-mw.parts
var newTplEndOffset = getDSR(tplInfo, s2,
false); // will succeed because it traverses non-tpl content
tplDsr = DU.getDataParsoid(tplInfo.first).dsr;
var tplEndOffset = tplDsr[1];
@@ -282,6 +289,7 @@
container: doc.createElement('section'),
// lowest possible level since we don't want
// any nesting of h-tags in the lead section
+ debug_id: 0,
level: 6,
lead: true,
};
diff --git a/tests/parserTests.txt b/tests/parserTests.txt
index 3d6e6a9..be7f01a 100644
--- a/tests/parserTests.txt
+++ b/tests/parserTests.txt
@@ -29989,8 +29989,43 @@
# Because of section-wrapping and template-wrapping interactions,
# the scope of the template is expanded so that the template markup
# is valid in the presence of <section> tags.
+# This exercises the s1 is null scenario in the wrapSections code
!! test
Section wrapping with template-generated sections (bad nesting 1)
+!! options
+parsoid={
+ "wrapSections": true
+}
+!! wikitext
+<div>
+a
+
+{{echo|
+= 1 =
+b
+}}
+
+c
+</div>
+!! html/parsoid
+<section data-mw-section-id="-1"></section><section
data-mw-section-id="-2"><div data-parsoid='{"stx":"html"}'>
+<p>a</p>
+
+<span about="#mwt1" typeof="mw:Transclusion"
data-parsoid='{"pi":[[{"k":"1"}]]}'
data-mw='{"parts":[{"template":{"target":{"wt":"echo","href":"./Template:Echo"},"params":{"1":{"wt":"\n=
1 =\nb\n"}},"i":0}},"\n\nc\n"]}'>
+</span><section data-mw-section-id="-1" about="#mwt1"><h1 about="#mwt1"
id="2"> 1 </h1><span about="#mwt1">
+</span><p about="#mwt1">b
+</p><span about="#mwt1">
+
+</span><p about="#mwt1">c</p><span about="#mwt1">
+</span></section></div></section>
+!! end
+
+# Because of section-wrapping and template-wrapping interactions,
+# the scope of the template is expanded so that the template markup
+# is valid in the presence of <section> tags.
+# This exercises the s1 is ancestor of s2 scenario in the wrapSections code
+!! test
+Section wrapping with template-generated sections (bad nesting 2)
!! options
parsoid={
"wrapSections": true
@@ -30030,8 +30065,9 @@
# so that template wrapping semantics are valid whether section
# tags are retained or stripped. But, the template scope can expand
# greatly when accounting for section tags.
+# This exercises the s1 and s2 are in different subtrees scenario
!! test
-Section wrapping with template-generated sections (bad nesting 2)
+Section wrapping with template-generated sections (bad nesting 3)
!! options
parsoid={
"wrapSections": true,
--
To view, visit https://gerrit.wikimedia.org/r/394242
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I1fd22c781f3a37ae5fe91a643faee5287b2c0ada
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/services/parsoid
Gerrit-Branch: master
Gerrit-Owner: Subramanya Sastry <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits