diff --git a/test/webserver.js b/test/webserver.js
index 9ea02d21b..ee5e80255 100644
--- a/test/webserver.js
+++ b/test/webserver.js
@@ -80,7 +80,7 @@ WebServer.prototype = {
}
},
_handler: function (req, res) {
- var url = req.url;
+ var url = req.url.replace(/\/\//g, '/');
var urlParts = /([^?]*)((?:\?(.*))?)/.exec(url);
var pathPart = decodeURI(urlParts[1]), queryPart = urlParts[3];
var verbose = this.verbose;
@@ -172,6 +172,17 @@ WebServer.prototype = {
serveRequestedFile(filePath);
}
+ function escapeHTML(untrusted) {
+ // Escape untrusted input so that it can safely be used in a HTML response
+ // in HTML and in HTML attributes.
+ return untrusted
+ .replace(/&/g, '&')
+ .replace(//g, '>')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''');
+ }
+
function serveDirectoryIndex(dir) {
res.setHeader('Content-Type', 'text/html');
res.writeHead(200);
@@ -194,21 +205,34 @@ WebServer.prototype = {
res.write('..
\n');
}
files.forEach(function (file) {
- var stat = fs.statSync(path.join(dir, file));
+ var stat;
var item = pathPart + file;
- if (stat.isDirectory()) {
- res.write('' +
- file + '
\n');
- return;
+ var href = '';
+ var label = '';
+ var extraAttributes = '';
+ try {
+ stat = fs.statSync(path.join(dir, file));
+ } catch (e) {
+ href = encodeURI(item);
+ label = file + ' (' + e + ')';
+ extraAttributes = ' style="color:red"';
}
- var ext = path.extname(file).toLowerCase();
- if (ext === '.pdf') {
- res.write('' +
- file + '
\n');
- } else if (all) {
- res.write('' +
- file + '
\n');
+ if (stat) {
+ if (stat.isDirectory()) {
+ href = encodeURI(item);
+ label = file;
+ } else if (path.extname(file).toLowerCase() === '.pdf') {
+ href = '/web/viewer.html?file=' + encodeURIComponent(item);
+ label = file;
+ extraAttributes = ' target="pdf"';
+ } else if (all) {
+ href = encodeURI(item);
+ label = file;
+ }
+ }
+ if (label) {
+ res.write('' + escapeHTML(label) + '
\n');
}
});
if (files.length === 0) {