jenkins-bot has submitted this change and it was merged. Change subject: Fix crash while expanding templates on older wikis ......................................................................
Fix crash while expanding templates on older wikis * They still put the wikitext in *, which resulted in the input to the tokenizer being undefined. * Here we ensure it's a string. * Introduced in c4ae060af704d5c981e7c69df791b0c18a1d6567. Bug: T75526 Change-Id: I1f4b5f6a16f0f2b25a89b64f6bd3ae8243865868 --- M lib/mediawiki.ApiRequest.js M lib/mediawiki.tokenizer.peg.js 2 files changed, 76 insertions(+), 72 deletions(-) Approvals: Marcoil: Looks good to me, approved jenkins-bot: Verified diff --git a/lib/mediawiki.ApiRequest.js b/lib/mediawiki.ApiRequest.js index cc088d8..a0fcde4 100644 --- a/lib/mediawiki.ApiRequest.js +++ b/lib/mediawiki.ApiRequest.js @@ -404,42 +404,43 @@ util.inherits( PreprocessorRequest, ApiRequest ); PreprocessorRequest.prototype._handleJSON = function ( error, data ) { + if ( !error && !(data && data.expandtemplates) ) { + error = new Error( util.format('Expanding template for %s: %s', + this.title, this.text) ); + } + if ( error ) { - this.env.log("error", error); + this.env.log( "error", error ); this._processListeners( error, '' ); return; } var src = ''; - try { + if ( data.expandtemplates.wikitext !== undefined ) { src = data.expandtemplates.wikitext; - } catch ( e2 ) { - error = new DoesNotExistError( 'Did not find page revisions in the returned body for ' + - this.title + e2 ); + } else if ( data.expandtemplates["*"] !== undefined ) { + // For backwards compatibility. Older wikis still put the data here. + src = data.expandtemplates["*"]; } - if ( !error ) { - //console.warn( 'Page ' + title + ': got ' + src ); - this.env.tp( 'Expanded ', this.text, src ); + this.env.tp( 'Expanded ', this.text, src ); - // Add the categories which were added by parser functions directly - // into the page and not as in-text links. - if (data.expandtemplates.categories) { - for (var i in data.expandtemplates.categories) { - var category = data.expandtemplates.categories[i]; - src += '\n[[Category:' + category['*']; - if (category.sortkey) { - src += "|" + category.sortkey; - } - src += ']]'; + // Add the categories which were added by parser functions directly + // into the page and not as in-text links. + if (data.expandtemplates.categories) { + for (var i in data.expandtemplates.categories) { + var category = data.expandtemplates.categories[i]; + src += '\n[[Category:' + category['*']; + if (category.sortkey) { + src += "|" + category.sortkey; } + src += ']]'; } - - // Add the source to the cache - this.env.pageCache[this.text] = src; } - //console.log( this.listeners('src') ); + // Add the source to the cache + this.env.pageCache[this.text] = src; + this._processListeners( error, src ); }; @@ -510,72 +511,72 @@ var dummyDoc = domino.createDocument(); PHPParseRequest.prototype._handleJSON = function ( error, data ) { + if ( !error && !(data && data.parse) ) { + error = new Error( util.format('Parsing extension for %s: %s', + this.title, this.text) ); + } + if ( error ) { + this.env.log( "error", error ); this._processListeners( error, '' ); return; } var parsedHtml = ''; - try { - // Strip paragraph wrapper from the html + if ( data.parse.text['*'] !== undefined ) { parsedHtml = data.parse.text['*']; - } catch ( e2 ) { - error = new DoesNotExistError( 'Could not expand extension content for ' + - this.title + e2 ); } - if ( !error ) { - // Strip two trailing newlines that action=parse adds after any - // extension output - parsedHtml = parsedHtml.replace(/\n\n$/, ''); - // Also strip a paragraph wrapper, if any - parsedHtml = parsedHtml.replace(/(^<p>)|(<\/p>$)/g, ''); + // Strip two trailing newlines that action=parse adds after any + // extension output + parsedHtml = parsedHtml.replace(/\n\n$/, ''); - // Add the modules to the page data - var page = this.env.page; - var setPageProperty = function(src, property) { - if (src) { - // This info comes back from the MW API when extension tags are parsed. - // Since a page can have multiple extension tags, we can hit this code - // multiple times and run into an already initialized set. - if (!page[property]) { - page[property] = new Set(); - } - for (var i in src) { - page[property].add(src[i]); - } + // Also strip a paragraph wrapper, if any + parsedHtml = parsedHtml.replace(/(^<p>)|(<\/p>$)/g, ''); + + // Add the modules to the page data + var page = this.env.page; + var setPageProperty = function(src, property) { + if (src) { + // This info comes back from the MW API when extension tags are parsed. + // Since a page can have multiple extension tags, we can hit this code + // multiple times and run into an already initialized set. + if (!page[property]) { + page[property] = new Set(); } - }; - - setPageProperty(data.parse.modules, "extensionModules"); - setPageProperty(data.parse.modulescripts, "extensionModuleScripts"); - setPageProperty(data.parse.modulestyles, "extensionModuleStyles"); - setPageProperty(data.parse.modulemessages, "extensionModuleMessages"); - - // Add the categories which were added by extensions directly into the - // page and not as in-text links - if (data.parse.categories) { - for (var i in data.parse.categories) { - var category = data.parse.categories[i]; - - var link = dummyDoc.createElement("link"); - link.setAttribute("rel", "mw:PageProp/Category"); - - var href = this.env.page.relativeLinkPrefix + "Category:" + encodeURIComponent(category['*']); - if ( category.sortkey ) { - href += "#" + encodeURIComponent(category.sortkey); - } - link.setAttribute("href", href); - - parsedHtml += "\n" + link.outerHTML; + for (var i in src) { + page[property].add(src[i]); } } + }; - // Add the source to the cache - this.env.pageCache[this.text] = parsedHtml; + setPageProperty(data.parse.modules, "extensionModules"); + setPageProperty(data.parse.modulescripts, "extensionModuleScripts"); + setPageProperty(data.parse.modulestyles, "extensionModuleStyles"); + setPageProperty(data.parse.modulemessages, "extensionModuleMessages"); + + // Add the categories which were added by extensions directly into the + // page and not as in-text links + if (data.parse.categories) { + for (var i in data.parse.categories) { + var category = data.parse.categories[i]; + + var link = dummyDoc.createElement("link"); + link.setAttribute("rel", "mw:PageProp/Category"); + + var href = this.env.page.relativeLinkPrefix + "Category:" + encodeURIComponent(category['*']); + if ( category.sortkey ) { + href += "#" + encodeURIComponent(category.sortkey); + } + link.setAttribute("href", href); + + parsedHtml += "\n" + link.outerHTML; + } } - //console.log( this.listeners('parsedHtml') ); + // Add the source to the cache + this.env.pageCache[this.text] = parsedHtml; + this._processListeners( error, parsedHtml ); }; diff --git a/lib/mediawiki.tokenizer.peg.js b/lib/mediawiki.tokenizer.peg.js index 44f7900..6104330 100644 --- a/lib/mediawiki.tokenizer.peg.js +++ b/lib/mediawiki.tokenizer.peg.js @@ -151,6 +151,9 @@ this.initTokenizer(); } + // ensure we're processing text + text = String(text || ""); + // Some input normalization: force a trailing newline //if ( text.substring(text.length - 1) !== "\n" ) { // text += "\n"; -- To view, visit https://gerrit.wikimedia.org/r/175930 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I1f4b5f6a16f0f2b25a89b64f6bd3ae8243865868 Gerrit-PatchSet: 3 Gerrit-Project: mediawiki/services/parsoid Gerrit-Branch: master Gerrit-Owner: Arlolra <abrea...@wikimedia.org> Gerrit-Reviewer: Arlolra <abrea...@wikimedia.org> Gerrit-Reviewer: Cscott <canan...@wikimedia.org> Gerrit-Reviewer: GWicke <gwi...@wikimedia.org> Gerrit-Reviewer: Jackmcbarn <jackmcb...@gmail.com> Gerrit-Reviewer: Kelson <kel...@kiwix.org> Gerrit-Reviewer: Marcoil <marc...@wikimedia.org> Gerrit-Reviewer: Subramanya Sastry <ssas...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits