Skip to content

Commit

Permalink
Merge branch 'copy:master' into fake-network-refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
chschnell authored Nov 18, 2024
2 parents 7cbd89c + f767d4d commit c5557a6
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 6 deletions.
48 changes: 43 additions & 5 deletions src/browser/fetch_network.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,14 @@ async function on_data_http(data)

let req_headers = new Headers();
for(let i = 1; i < headers.length; ++i) {
let parts = headers[i].split(": ");
let key = parts[0].toLowerCase();
let value = parts[1];
if( key === "host" ) target.host = value;
else if( key.length > 1 ) req_headers.set(parts[0], value);
const header = this.net.parse_http_header(headers[i]);
if(!header) {
console.warn('The request contains an invalid header: "%s"', headers[i]);
this.write(new TextEncoder().encode("HTTP/1.1 400 Bad Request\r\nContent-Length: 0"));
return;
}
if( header.key.toLowerCase() === "host" ) target.host = header.value;
else req_headers.append(header.key, header.value);
}

dbg_log("HTTP Dispatch: " + target.href, LOG_FETCH);
Expand Down Expand Up @@ -153,6 +156,41 @@ FetchNetworkAdapter.prototype.fetch = async function(url, options)
}
};

FetchNetworkAdapter.prototype.parse_http_header = function(header)
{
const parts = header.match(/^([^:]*):(.*)$/);
if(!parts) {
dbg_log("Unable to parse HTTP header", LOG_FETCH);
return;
}

const key = parts[1];
const value = parts[2].trim();

if(key.length === 0)
{
dbg_log("Header key is empty, raw header", LOG_FETCH);
return;
}
if(value.length === 0)
{
dbg_log("Header value is empty", LOG_FETCH);
return;
}
if(!/^[\w-]+$/.test(key))
{
dbg_log("Header key contains forbidden characters", LOG_FETCH);
return;
}
if(!/^[\x20-\x7E]+$/.test(value))
{
dbg_log("Header value contains forbidden characters", LOG_FETCH);
return;
}

return { key, value };
};

/**
* @param {Uint8Array} data
*/
Expand Down
40 changes: 39 additions & 1 deletion tests/devices/fetch_network.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,45 @@ const tests =
assert(/This domain is for use in illustrative examples in documents/.test(capture), "got example.org text");
},
},

{
name: "Forbidden character in header name",
start: () =>
{
emulator.serial0_send("wget --header='test.v86: 123' -T 10 -O - test.domain\n");
emulator.serial0_send("echo -e done\\\\tincorrect header name\n");
},
end_trigger: "done\tincorrect header name",
end: (capture) =>
{
assert(/400 Bad Request/.test(capture), "got error 400");
},
},
{
name: "Empty header value",
start: () =>
{
emulator.serial0_send("wget --header='test:' -T 10 -O - test.domain\n");
emulator.serial0_send("echo -e done\\\\tempty header value\n");
},
end_trigger: "done\tempty header value",
end: (capture) =>
{
assert(/400 Bad Request/.test(capture), "got error 400");
},
},
{
name: "Header without separator",
start: () =>
{
emulator.serial0_send("wget --spider --header='testheader' -T 10 -O - test.domain\n");
emulator.serial0_send("echo -e done\\\\theader without colon\n");
},
end_trigger: "done\theader without colon",
end: (capture) =>
{
assert(/400 Bad Request/.test(capture), "got error 400");
},
}
];

const emulator = new V86({
Expand Down

0 comments on commit c5557a6

Please sign in to comment.