Skip to content
This repository has been archived by the owner on Oct 30, 2020. It is now read-only.

Commit

Permalink
Merge pull request #15 from the-grid/safer-json
Browse files Browse the repository at this point in the history
Safer JSON transport method
  • Loading branch information
jonnor authored Aug 22, 2016
2 parents f2eb86a + d5d0c5b commit 334d40c
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 14 deletions.
22 changes: 21 additions & 1 deletion spec/runner.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ describe 'Runner', ->
chai.expect(err.message).to.contain 'TIMEOUT'
done()

describe 'input data containing </script>', ->
describe 'input data containing <script>...</script>', ->
it 'should succeed', (done) ->
filter = local 'return-input'
input = { 'foo': 'barbaz', 'htmlscript': '<script>alert("Works!")</script>' }
Expand All @@ -376,6 +376,26 @@ describe 'Runner', ->
chai.expect(solution).to.eql input
done()

describe 'input data containing </script>...<script>', ->
it 'should succeed', (done) ->
filter = local 'return-input'
input = { 'foo': 'barbaz', 'htmlbogusscript': '</script> <script>alert("Works!")</script> <script>' }
options = {}
solver.runJob filter, input, options, (err, solution, details) ->
chai.expect(err).to.not.exist
chai.expect(solution).to.eql input
done()

describe 'input data containing HTML comment', ->
it 'should succeed', (done) ->
filter = local 'return-input'
input = { 'foo': 'barbaz', 'htmlcomment': '<!-- FFOO -->' }
options = {}
solver.runJob filter, input, options, (err, solution, details) ->
chai.expect(err).to.not.exist
chai.expect(solution).to.eql input
done()

describe 'filter with infinite loop', ->
it 'should timeout and return error', (done) ->
@timeout 9000
Expand Down
48 changes: 35 additions & 13 deletions src/runner.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ htmlEscape = (html) ->
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')

generateHtml = (filter, page, options) ->
generateHtml = (filter, options) ->

library = """
window.jsJobEvent = function(id, payload) {
Expand All @@ -45,6 +45,19 @@ generateHtml = (filter, page, options) ->
}
return obj;
};
var getData = function(callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', window.location.href+'/data', false);
xhr.setRequestHeader('Content-type', 'application/json; charset=utf-8');
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
var json = xhr.responseText;
var data = JSON.parse(json);
return callback(null, data);
}
};
xhr.send();
};
var sendResponse = function(err, solution, details) {
var xhr = new XMLHttpRequest();
xhr.open('POST', window.location.href, true);
Expand All @@ -63,20 +76,17 @@ generateHtml = (filter, page, options) ->
};
var main = function() {
console.log('poly: main start');
var dataElement = document.getElementById("poly-input-data");
var json = dataElement.innerHTML.substring("<!--".length, dataElement.innerHTML.length-"-->".length);
var data = JSON.parse(json);
console.log('poly: starting solving');
window.jsJobRun(data.page, data.options, cb);
console.log('poly: started');
getData(function(err, data) {
console.log('poly: starting solving');
window.jsJobRun(data.input, data.options, cb);
console.log('poly: started');
});
};
window.onload = main;
// main();
"""

payload = { page: page, options: options }
json = JSON.stringify payload, null, 4

scriptTags = ("<script>#{s}</script>" for s in options.scripts).join("\n")
body = """<!DOCTYPE html>
<html>
Expand All @@ -85,7 +95,6 @@ generateHtml = (filter, page, options) ->
#{scriptTags}
<script>#{library}</script>
<script src="#{filter}"></script>
<script id="poly-input-data" type="application/json"><!--#{json}--></script>
</head>
<body>
<script>#{script}</script>
Expand Down Expand Up @@ -186,11 +195,25 @@ class Runner
jobId = paths[2]
if paths[3] == 'event'
return @handleEventRequest jobId, request, response
else if paths[3] == 'data'
return @handleDataRequest jobId, request, response
else
return response.end()
else
return response.end()

handleDataRequest: (jobId, request, response) ->
console.log "#{request.method} #{jobId}" if @options.verbose
job = @jobs[jobId]
if not job
# multiple callbacks for same id, or wrong id
debug 'could not find solve job', jobId
return

response.writeHead 200, {"Content-Type": "application/json; charset=utf-8"}
body = JSON.stringify { input: job.page, options: job.options }
response.end body

handleSolveRequest: (jobId, request, response) ->
console.log "#{request.method} #{jobId}" if @options.verbose
job = @jobs[jobId]
Expand All @@ -200,9 +223,8 @@ class Runner
return

if request.method == 'GET'
# FIXME: make only for GET
response.writeHead 200, {"Content-Type": "text/html; charset=utf-8"}
body = generateHtml job.filter, job.page, job.options
body = generateHtml job.filter, job.options
response.end body
else if request.method == 'POST'
data = ""
Expand Down

0 comments on commit 334d40c

Please sign in to comment.