Skip to content
This repository has been archived by the owner on Jan 12, 2024. It is now read-only.

Commit

Permalink
fail gracefully on errorneous stylesheet input (fixes #367, #430)
Browse files Browse the repository at this point in the history
  • Loading branch information
nebulon42 committed Mar 4, 2016
1 parent 2181629 commit cdf3215
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 33 deletions.
20 changes: 13 additions & 7 deletions bin/carto
Original file line number Diff line number Diff line change
Expand Up @@ -166,13 +166,19 @@ if (ext == '.mml') {
nosymlink: options.nosymlink
}, compileMML);
} else {
data.Stylesheet = data.Stylesheet.map(function(x) {
if (typeof x !== 'string') {
return { id: x, data: x.data }
}
return { id: x, data: fs.readFileSync(path.join(path.dirname(input), x), 'utf8') }
});
compileMML(null,data);
if (_.has(data, 'Stylesheet') && !_.isNil(data.Stylesheet)) {
data.Stylesheet = _.castArray(data.Stylesheet);
data.Stylesheet = data.Stylesheet.map(function(x) {
if (typeof x !== 'string') {
return { id: x, data: x.data }
}
return { id: x, data: fs.readFileSync(path.join(path.dirname(input), x), 'utf8') }
});
compileMML(null,data);
}
else {
console.error("Expecting a Stylesheet property containing an (array of) stylesheet object(s) of the form { id: 'x', 'data': 'y' }.");
}
}
} else if (ext == '.mss') {
compileMSS(null,data);
Expand Down
46 changes: 28 additions & 18 deletions lib/carto/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ carto.Renderer.prototype.renderMSS = function render(data) {

/**
* Prepare a MML document (given as an object) into a
* fully-localized XML file ready for Mapnik2 consumption
* fully-localized XML file ready for Mapnik consumption
*
* @param {String} m - the JSON file as a string.
*/
Expand All @@ -80,23 +80,33 @@ carto.Renderer.prototype.render = function render(m) {
var output = [];

// Transform stylesheets into definitions.
var definitions = _(m.Stylesheet).chain()
.map(function(s) {
if (typeof s == 'string') {
throw new Error("Stylesheet object is expected not a string: '" + s + "'");
}
// Passing the environment from stylesheet to stylesheet,
// allows frames and effects to be maintained.
env = _(env).extend({filename:s.id}).value();

var time = +new Date(),
root = (carto.Parser(env)).parse(s.data);
if (env.benchmark)
console.warn('Parsing time: ' + (new Date() - time) + 'ms');
return root.toList(env);
})
.flatten()
.value();
if (_.has(m, 'Stylesheet') && !_.isNil(m.Stylesheet)) {
m.Stylesheet = _.castArray(m.Stylesheet);
var definitions = _(m.Stylesheet).chain()
.map(function(s) {
if (_.isString(s) || !_.has(s, 'id') || !_.has(s, 'data') || _.isNil(s.id) || _.isNil(s.data)) {
var e = new Error("Expecting a stylesheet object of the form { id: 'x', 'data': 'y' } for the Stylesheet property.\n");
e.stack = null; // do not show stack trace
throw e;
}
// Passing the environment from stylesheet to stylesheet,
// allows frames and effects to be maintained.
env = _(env).extend({filename:s.id}).value();

var time = +new Date(),
root = (carto.Parser(env)).parse(s.data);
if (env.benchmark)
console.warn('Parsing time: ' + (new Date() - time) + 'ms');
return root.toList(env);
})
.flatten()
.value();
}
else {
var e = new Error("Expecting a Stylesheet property containing an (array of) stylesheet object(s) of the form { id: 'x', 'data': 'y' }.\n");
e.stack = null; // do not show stack trace
throw e;
}

function appliesTo(name, classIndex) {
return function(definition) {
Expand Down
7 changes: 7 additions & 0 deletions test/errorhandling/no_stylesheet.mml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"Layer": [
{
"name": "a"
}
]
}
1 change: 1 addition & 0 deletions test/errorhandling/no_stylesheet.result
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expecting a Stylesheet property containing an (array of) stylesheet object(s) of the form { id: 'x', 'data': 'y' }.
10 changes: 10 additions & 0 deletions test/errorhandling/stylesheet_no_data.mml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Layer": [
{
"name": "a"
}
],
"Stylesheet": [{
"id": "b"
}]
}
1 change: 1 addition & 0 deletions test/errorhandling/stylesheet_no_data.result
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expecting a stylesheet object of the form { id: 'x', 'data': 'y' } for the Stylesheet property.
10 changes: 10 additions & 0 deletions test/errorhandling/stylesheet_no_id.mml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"Layer": [
{
"name": "a"
}
],
"Stylesheet": [{
"data": "test"
}]
}
1 change: 1 addition & 0 deletions test/errorhandling/stylesheet_no_id.result
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expecting a stylesheet object of the form { id: 'x', 'data': 'y' } for the Stylesheet property.
24 changes: 16 additions & 8 deletions test/support/helper.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
var path = require('path'),
_ = require('lodash'),
fs = require('fs'),
assert = require('assert'),
crypto = require('crypto'),
sax = require('sax'),
diff = require('./diff').diff,
yaml = require('js-yaml'),
_ = require('lodash'),
constants = ((!process.ENOENT) >= 1) ?
require('constants') :
{ ENOENT: process.ENOENT };
Expand Down Expand Up @@ -36,13 +37,20 @@ exports.json = function(file, callback) {
};

exports.mml = function(file) {
var mml = JSON.parse(fs.readFileSync(file, 'utf-8'));
mml.Stylesheet = _(mml.Stylesheet).map(function(s) {
return {
id: s,
data: fs.readFileSync(path.join(path.dirname(file), s), 'utf-8')
};
});
var mml = yaml.safeLoad(fs.readFileSync(file, 'utf-8'));
if (!_.isNil(mml.Stylesheet)) {
mml.Stylesheet = mml.Stylesheet.map(function(s) {
if (path.extname(s) === '.mss') {
return {
id: s,
data: fs.readFileSync(path.join(path.dirname(file), s), 'utf-8')
};
}
else {
return s;
}
});
}
return mml;
};

Expand Down

0 comments on commit cdf3215

Please sign in to comment.