diff options
author | Samy Pessé <samypesse@gmail.com> | 2015-09-15 11:09:08 +0200 |
---|---|---|
committer | Samy Pessé <samypesse@gmail.com> | 2015-09-15 11:09:08 +0200 |
commit | baf10e9b159b64c30ce650c83eb437675434e3e2 (patch) | |
tree | 583fc00922e6ca52fea87947af0b4d5703aabf7d /lib | |
parent | 463a947df1e5c8c862c555a5b0ae675e356a0d5c (diff) | |
download | gitbook-baf10e9b159b64c30ce650c83eb437675434e3e2.zip gitbook-baf10e9b159b64c30ce650c83eb437675434e3e2.tar.gz gitbook-baf10e9b159b64c30ce650c83eb437675434e3e2.tar.bz2 |
Improve book.resolve to ensure file is in the book
Adapt tests to plugin-highlight
Diffstat (limited to 'lib')
-rw-r--r-- | lib/book.js | 43 | ||||
-rw-r--r-- | lib/template.js | 8 | ||||
-rw-r--r-- | lib/utils/navigation.js | 9 |
3 files changed, 47 insertions, 13 deletions
diff --git a/lib/book.js b/lib/book.js index b306c51..980e505 100644 --- a/lib/book.js +++ b/lib/book.js @@ -630,21 +630,27 @@ Book.prototype.findFile = function(filename) { // Check if a file exists in the book Book.prototype.fileExists = function(filename) { return fs.exists( - path.join(this.root, filename) + this.resolve(filename) ); }; +// Check if a file path is inside the book +Book.prototype.fileIsInBook = function(filename) { + filename = path.normalize(filename); + return (filename.substr(0, this.root.length) === this.root); +}; + // Read a file Book.prototype.readFile = function(filename) { return fs.readFile( - path.join(this.root, filename), + this.resolve(filename), { encoding: "utf8" } ); }; // Return stat for a file Book.prototype.statFile = function(filename) { - return fs.stat(path.join(this.root, filename)); + return fs.stat(this.resolve(filename)); }; // List all files in the book @@ -702,9 +708,34 @@ Book.prototype.isEntryPoint = function(fp) { return fp == this.readmeFile; }; -// Resolve a path in book -Book.prototype.resolve = function(p) { - return path.resolve(this.root, p); +// Alias to book.config.get +Book.prototype.getConfig = function(key, def) { + return this.config.get(key, def); +}; + +// Resolve a path in the book source +// Enforce that the output path in the root folder +Book.prototype.resolve = function() { + var input = _.chain(arguments) + .toArray() + .reduce(function(current, p) { + // Handle path relative to book root ('/README.md') + if (p[0] == '/' || p[0] == '\\') return p.slice(1); + + return path.join(current, p); + }) + .value(); + + + var result = path.resolve(this.root, input); + + if (!this.fileIsInBook(result)) { + err = new Error("EACCESS: '" + result + "' not in '" + this.root + "'"); + err.code = "EACCESS"; + throw err; + } + + return result }; // Normalize a path to .html and convert README -> index diff --git a/lib/template.js b/lib/template.js index 4b2035f..b1bc632 100644 --- a/lib/template.js +++ b/lib/template.js @@ -30,7 +30,7 @@ var BookLoader = nunjucks.Loader.extend({ git.resolveFile(fileurl) .then(function(filepath) { // Is local file - if (!filepath) filepath = that.book.resolve(fileurl); + if (!filepath) filepath = path.resolve(fileurl); else that.book.log.debug.ln("resolve from git", fileurl, "to", filepath) // Read file from absolute path @@ -46,6 +46,12 @@ var BookLoader = nunjucks.Loader.extend({ }, resolve: function(from, to) { + // If origin is in the book, we enforce result file to be in the book + if (this.book.fileIsInBook(from)) { + return this.book.resolve(path.dirname(from), to); + } + + // If origin is not in the book (include from a git content ref) return path.resolve(path.dirname(from), to); } }); diff --git a/lib/utils/navigation.js b/lib/utils/navigation.js index af9330d..d825c2c 100644 --- a/lib/utils/navigation.js +++ b/lib/utils/navigation.js @@ -27,7 +27,7 @@ function navigation(summary, files) { files = _.isArray(files) ? files : (_.isString(files) ? [files] : null); // List of all navNodes - // Flatten chapters, then add in default README node if needed etc ... + // Flatten chapters var navNodes = flattenChapters(summary.chapters); // Mapping of prev/next for a give path @@ -39,8 +39,7 @@ function navigation(summary, files) { if(!current.exists) return null; // Find prev - prev = _.chain(navNodes) - .slice(0, i) + prev = _.chain(navNodes.slice(0, i)) .reverse() .find(function(node) { return node.exists && !node.external; @@ -48,14 +47,12 @@ function navigation(summary, files) { .value(); // Find next - next = _.chain(navNodes) - .slice(i+1) + next = _.chain(navNodes.slice(i+1)) .find(function(node) { return node.exists && !node.external; }) .value(); - return [current.path, { index: i, title: current.title, |