diff options
| author | Michael Williamson <mike@zwobble.org> | 2013-04-27 17:04:37 +0100 |
|---|---|---|
| committer | Michael Williamson <mike@zwobble.org> | 2013-04-27 17:04:37 +0100 |
| commit | edc871d3aa33bded7ee766a7374fcdbfe93a01bd (patch) | |
| tree | c4fc676f9c3d4f0bfdc0b6984c3da57581c787f2 | |
| parent | 54c5c0ee38eb915275be4b0713fcaafb56033ac3 (diff) | |
Use getElementsByTagName for safer image parsing
| -rw-r--r-- | lib/document-xml-reader.js | 33 | ||||
| -rw-r--r-- | lib/results.js | 9 | ||||
| -rw-r--r-- | lib/xmlreader.js | 15 | ||||
| -rw-r--r-- | tests/document-xml-reader.tests.js | 9 |
4 files changed, 50 insertions, 16 deletions
diff --git a/lib/document-xml-reader.js b/lib/document-xml-reader.js index a391a21..1724b5b 100644 --- a/lib/document-xml-reader.js +++ b/lib/document-xml-reader.js @@ -23,9 +23,7 @@ function DocumentXmlReader(relationships, docxFile) { function readXmlElements(elements) { var results = elements.map(readXmlElement); - var values = _.flatten(_.pluck(results, "value")); - var messages = _.flatten(_.pluck(results, "messages"), true); - return new Result(values, messages); + return Result.combine(results); } function readXmlElement(element) { @@ -108,19 +106,24 @@ function DocumentXmlReader(relationships, docxFile) { return readXmlElements(element.children); }, "wp:inline": function(element) { - var relationshipId = element - .first("a:graphic") - .first("a:graphicData") - .first("pic:pic") - .first("pic:blipFill") - .first("a:blip") - .attributes["r:embed"]; - var imagePath = relationships[relationshipId].target; - var readImage = docxFile.read.bind(docxFile, path.join("word", imagePath)); - var altText = element.first("wp:docPr").attributes.descr; + var blips = element + .getElementsByTagName("a:graphic") + .getElementsByTagName("a:graphicData") + .getElementsByTagName("pic:pic") + .getElementsByTagName("pic:blipFill") + .getElementsByTagName("a:blip"); - var image = documents.Image(readImage, altText) - return new Result(image); + var results = blips.map(function(blip) { + var relationshipId = blip.attributes["r:embed"]; + var imagePath = relationships[relationshipId].target; + var readImage = docxFile.read.bind(docxFile, path.join("word", imagePath)); + var altText = element.first("wp:docPr").attributes.descr; + + var image = documents.Image(readImage, altText) + return new Result(image); + }); + + return Result.combine(results); } }; return { diff --git a/lib/results.js b/lib/results.js index d5dd7af..c12d194 100644 --- a/lib/results.js +++ b/lib/results.js @@ -1,3 +1,6 @@ +var _ = require("underscore"); + + exports.Result = Result; exports.warning = warning; @@ -18,6 +21,12 @@ Result.prototype.flatMapThen = function(func) { }); }; +Result.combine = function(results) { + var values = _.flatten(_.pluck(results, "value")); + var messages = _.flatten(_.pluck(results, "messages"), true); + return new Result(values, messages); +}; + function warning(message) { return { type: "warning", diff --git a/lib/xmlreader.js b/lib/xmlreader.js index 08347c4..3b14a93 100644 --- a/lib/xmlreader.js +++ b/lib/xmlreader.js @@ -99,7 +99,20 @@ Element.prototype.first = function(name) { } Element.prototype.getElementsByTagName = function(name) { - return _.filter(this.children, function(child) { + var elements = _.filter(this.children, function(child) { return child.name == name; }); + return toElementList(elements); }; + +var elementListPrototype = { + getElementsByTagName: function(name) { + return toElementList(_.flatten(this.map(function(element) { + return element.getElementsByTagName(name); + }, true))); + } +}; + +function toElementList(array) { + return _.extend(array, elementListPrototype); +} diff --git a/tests/document-xml-reader.tests.js b/tests/document-xml-reader.tests.js index 51512eb..8edcf72 100644 --- a/tests/document-xml-reader.tests.js +++ b/tests/document-xml-reader.tests.js @@ -143,6 +143,15 @@ describe("readXmlElement: ", function() { assert.deepEqual(result.messages, []); assert.deepEqual(result.value, []); }); + + test("no elements created if image cannot be found in wp:inline", function() { + var drawing = new XmlElement("wp:inline", {}, []); + + var reader = new DocumentXmlReader(); + var result = reader.readXmlElement(drawing); + assert.deepEqual(result.messages, []); + assert.deepEqual(result.value, []); + }); }); function runWithProperties(children) { |
