Bug 686429: test cases for MIME headers need refactoring; r=bz

This commit is contained in:
Julian Reschke 2011-10-12 20:30:22 +02:00
parent eb2cb918a4
commit 9c5cefdd09
7 changed files with 185 additions and 236 deletions

View File

@ -1,152 +1,256 @@
/**
* Test for bug 588781: ensure that for a MIME parameter with both "filename"
* and "filename*" we pick the RFC2231/5987 encoded form
* Tests for parsing header fields using the syntax used in
* Content-Disposition and Content-Type
*
* Note: RFC 5987 drops support for continuations (foo*0, foo*1*, etc.).
*
* See also <http://greenbytes.de/tech/webdav/rfc5987.html#rfc.section.4.2>
* See also https://bugzilla.mozilla.org/show_bug.cgi?id=609667
*/
const Cr = Components.results;
var BS = '\\';
var DQUOTE = '"';
// Test array:
// - element 0: "Content-Disposition" header to test for 'filename' parameter
// - element 1: correct value returned under RFC 2231 (email)
// - element 2: correct value returned under RFC 5987 (HTTP)
// - element 0: "Content-Disposition" header to test
// under RFC 2231 (email):
// - element 1: correct value returned for disposition-type (empty param name)
// - element 2: correct value for filename returned
// under RFC 5987 (HTTP):
// (note: 5987-mode not yet in use, see bug 601933)
// - element 3: correct value returned for disposition-type (empty param name)
// - element 4: correct value for filename returned
//
// 3 and 4 may be left out if they are identical
var tests = [
// No filename parameter: return nothing
["attachment;",
Cr.NS_ERROR_INVALID_ARG, Cr.NS_ERROR_INVALID_ARG],
["attachment;",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// basic
["attachment; filename=basic",
"basic", "basic"],
"attachment", "basic"],
// extended
["attachment; filename*=UTF-8''extended",
"extended", "extended"],
"attachment", "extended"],
// prefer extended to basic
// prefer extended to basic (bug 588781)
["attachment; filename=basic; filename*=UTF-8''extended",
"extended", "extended"],
"attachment", "extended"],
// prefer extended to basic
// prefer extended to basic (bug 588781)
["attachment; filename*=UTF-8''extended; filename=basic",
"extended", "extended"],
"attachment", "extended"],
// use first basic value
// use first basic value (invalid; error recovery)
["attachment; filename=first; filename=wrong",
"first", "first"],
"attachment", "first"],
// old school bad HTTP servers: missing 'attachment' or 'inline'
// (invalid; error recovery)
["filename=old",
"old", "old"],
"filename=old", "old"],
["attachment; filename*=UTF-8''extended",
"extended", "extended"],
"attachment", "extended"],
// continuations not part of RFC 5987 (bug 610054)
["attachment; filename*0=foo; filename*1=bar",
"foobar", Cr.NS_ERROR_INVALID_ARG],
"attachment", "foobar",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// Return first continuation
// Return first continuation (invalid; error recovery)
["attachment; filename*0=first; filename*0=wrong; filename=basic",
"first", "basic"],
"attachment", "first",
"attachment", "basic"],
// Only use correctly ordered continuations
// Only use correctly ordered continuations (invalid; error recovery)
["attachment; filename*0=first; filename*1=second; filename*0=wrong",
"firstsecond", Cr.NS_ERROR_INVALID_ARG],
"attachment", "firstsecond",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// prefer continuation to basic (unless RFC 5987)
["attachment; filename=basic; filename*0=foo; filename*1=bar",
"foobar", "basic"],
"attachment", "foobar",
"attachment", "basic"],
// Prefer extended to basic and/or (broken or not) continuation
// (invalid; error recovery)
["attachment; filename=basic; filename*0=first; filename*0=wrong; filename*=UTF-8''extended",
"extended", "extended"],
"attachment", "extended"],
// RFC 2231 not clear on correct outcome: we prefer non-continued extended
// (invalid; error recovery)
["attachment; filename=basic; filename*=UTF-8''extended; filename*0=foo; filename*1=bar",
"extended", "extended"],
"attachment", "extended"],
// Gaps should result in returning only value until gap hit
// (invalid; error recovery)
["attachment; filename*0=foo; filename*2=bar",
"foo", Cr.NS_ERROR_INVALID_ARG],
"attachment", "foo",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// Don't allow leading 0's (*01)
// Don't allow leading 0's (*01) (invalid; error recovery)
["attachment; filename*0=foo; filename*01=bar",
"foo", Cr.NS_ERROR_INVALID_ARG],
"attachment", "foo",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// continuations should prevail over non-extended (unless RFC 5987)
["attachment; filename=basic; filename*0*=UTF-8''multi\r\n"
+ " filename*1=line\r\n"
+ " filename*2*=%20extended",
"multiline extended", "basic"],
"attachment", "multiline extended",
"attachment", "basic"],
// Gaps should result in returning only value until gap hit
// (invalid; error recovery)
["attachment; filename=basic; filename*0*=UTF-8''multi\r\n"
+ " filename*1=line\r\n"
+ " filename*3*=%20extended",
"multiline", "basic"],
"attachment", "multiline",
"attachment", "basic"],
// First series, only please, and don't slurp up higher elements (*2 in this
// case) from later series into earlier one
// case) from later series into earlier one (invalid; error recovery)
["attachment; filename=basic; filename*0*=UTF-8''multi\r\n"
+ " filename*1=line\r\n"
+ " filename*0*=UTF-8''wrong\r\n"
+ " filename*1=bad\r\n"
+ " filename*2=evil",
"multiline", "basic"],
"attachment", "multiline",
"attachment", "basic"],
// RFC 2231 not clear on correct outcome: we prefer non-continued extended
// (invalid; error recovery)
["attachment; filename=basic; filename*0=UTF-8''multi\r\n"
+ " filename*=UTF-8''extended\r\n"
+ " filename*1=line\r\n"
+ " filename*2*=%20extended",
"extended", "extended"],
"attachment", "extended"],
// sneaky: if unescaped, make sure we leave UTF-8'' in value
["attachment; filename*0=UTF-8''unescaped\r\n"
+ " filename*1*=%20so%20includes%20UTF-8''%20in%20value",
"UTF-8''unescaped so includes UTF-8'' in value", Cr.NS_ERROR_INVALID_ARG],
"attachment", "UTF-8''unescaped so includes UTF-8'' in value",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// sneaky: if unescaped, make sure we leave UTF-8'' in value
["attachment; filename=basic; filename*0=UTF-8''unescaped\r\n"
+ " filename*1*=%20so%20includes%20UTF-8''%20in%20value",
"UTF-8''unescaped so includes UTF-8'' in value", "basic"],
"attachment", "UTF-8''unescaped so includes UTF-8'' in value",
"attachment", "basic"],
// Prefer basic over invalid continuation
// (invalid; error recovery)
["attachment; filename=basic; filename*1=multi\r\n"
+ " filename*2=line\r\n"
+ " filename*3*=%20extended",
"basic", "basic"],
"attachment", "basic"],
// support digits over 10
["attachment; filename=basic; filename*0*=UTF-8''0\r\n"
+ " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5\r\n"
+ " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a\r\n"
+ " filename*11=b; filename*12=c;filename*13=d;filename*14=e;filename*15=f\r\n",
"0123456789abcdef", "basic"],
"attachment", "0123456789abcdef",
"attachment", "basic"],
// support digits over 10 (check ordering)
["attachment; filename=basic; filename*0*=UTF-8''0\r\n"
+ " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5\r\n"
+ " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a\r\n"
+ " filename*11=b; filename*12=c;filename*13=d;filename*15=f;filename*14=e\r\n",
"0123456789abcd" /* should see the 'f', see bug 588414 */, "basic"],
"attachment", "0123456789abcd" /* should see the 'f', see bug 588414 */,
"attachment", "basic"],
// support digits over 10 (detect gaps)
["attachment; filename=basic; filename*0*=UTF-8''0\r\n"
+ " filename*1=1; filename*2=2;filename*3=3;filename*4=4;filename*5=5\r\n"
+ " filename*6=6; filename*7=7;filename*8=8;filename*9=9;filename*10=a\r\n"
+ " filename*11=b; filename*12=c;filename*14=e\r\n",
"0123456789abc", "basic"],
"attachment", "0123456789abc",
"attachment", "basic"],
// return nothing: invalid
// (invalid; error recovery)
["attachment; filename*1=multi\r\n"
+ " filename*2=line\r\n"
+ " filename*3*=%20extended",
Cr.NS_ERROR_INVALID_ARG, Cr.NS_ERROR_INVALID_ARG],
"attachment", Cr.NS_ERROR_INVALID_ARG],
// Bug 272541: Empty disposition type treated as "attachment"
// sanity check
["attachment; filename=foo.html",
"attachment", "foo.html",
"attachment", "foo.html"],
// the actual bug
["; filename=foo.html",
Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY, "foo.html",
Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY, "foo.html"],
// regression check, but see bug 671204
["filename=foo.html",
"filename=foo.html", "foo.html",
"filename=foo.html", "foo.html"],
// Bug 419157: ensure that a MIME parameter with no charset information
// fallbacks to Latin-1
["attachment;filename=IT839\x04\xB5(m8)2.pdf;",
"attachment", "IT839\u0004\u00b5(m8)2.pdf"],
// Bug 588389: unescaping backslashes in quoted string parameters
// '\"', should be parsed as '"'
["attachment; filename=" + DQUOTE + (BS + DQUOTE) + DQUOTE,
"attachment", DQUOTE],
// 'a\"b', should be parsed as 'a"b'
["attachment; filename=" + DQUOTE + 'a' + (BS + DQUOTE) + 'b' + DQUOTE,
"attachment", "a" + DQUOTE + "b"],
// '\x', should be parsed as 'x'
["attachment; filename=" + DQUOTE + (BS + "x") + DQUOTE,
"attachment", "x"],
// test empty param (quoted-string)
["attachment; filename=" + DQUOTE + DQUOTE,
"attachment", ""],
// test empty param
["attachment; filename=",
"attachment", ""],
// Bug 651185: double quotes around 2231/5987 encoded param
// sanity check
["attachment; filename*=utf-8''%41",
"attachment", "A"],
// the actual bug
["attachment; filename*=" + DQUOTE + "utf-8''%41" + DQUOTE,
"attachment", Cr.NS_ERROR_INVALID_ARG],
// Bug 670333: Content-Disposition parser does not require presence of "="
// in params
// sanity check
["attachment; filename*=UTF-8''foo-%41.html",
"attachment", "foo-A.html"],
// the actual bug
["attachment; filename *=UTF-8''foo-%41.html",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// the actual bug, without 2231/5987 encoding
["attachment; filename X",
"attachment", Cr.NS_ERROR_INVALID_ARG],
// sanity check with WS on both sides
["attachment; filename = foo-A.html",
"attachment", "foo-A.html"],
];
function do_tests(whichRFC)
@ -157,21 +261,51 @@ function do_tests(whichRFC)
var unused = { value : null };
for (var i = 0; i < tests.length; ++i) {
dump("Testing " + tests[i] + "\n");
dump("Testing #" + i + ": " + tests[i] + "\n");
// check disposition type
var expectedDt = tests[i].length == 3 || whichRFC == 0 ? tests[i][1] : tests[i][3];
try {
var result;
if (whichRFC == 1)
result = mhp.getParameter(tests[i][0], "filename", "UTF-8", true, unused);
if (whichRFC == 0)
result = mhp.getParameter(tests[i][0], "", "UTF-8", true, unused);
else
result = mhp.getParameter5987(tests[i][0], "filename", "UTF-8", true, unused);
do_check_eq(result, tests[i][whichRFC]);
result = mhp.getParameter5987(tests[i][0], "", "UTF-8", true, unused);
do_check_eq(result, expectedDt);
}
catch (e) {
// Tests can also succeed by expecting to fail with given error code
if (e.result) {
// Allow following tests to run by catching exception from do_check_eq()
try {
do_check_eq(e.result, tests[i][whichRFC]);
do_check_eq(e.result, expectedDt);
} catch(e) {}
}
continue;
}
// check filename parameter
var expectedFn = tests[i].length == 3 || whichRFC == 0 ? tests[i][2] : tests[i][4];
try {
var result;
if (whichRFC == 0)
result = mhp.getParameter(tests[i][0], "filename", "UTF-8", true, unused);
else
result = mhp.getParameter5987(tests[i][0], "filename", "UTF-8", true, unused);
do_check_eq(result, expectedFn);
}
catch (e) {
// Tests can also succeed by expecting to fail with given error code
if (e.result) {
// Allow following tests to run by catching exception from do_check_eq()
try {
do_check_eq(e.result, expectedFn);
} catch(e) {}
}
continue;
@ -182,9 +316,9 @@ function do_tests(whichRFC)
function run_test() {
// Test RFC 2231
do_tests(1);
do_tests(0);
// Test RFC 5987
do_tests(2);
do_tests(1);
}

View File

@ -1,37 +0,0 @@
/**
* Test for bug 272541: - Empty disposition type treated as "attachment"
*/
const Cr = Components.results
var tests = [
[ /* the actual bug */
"; filename=foo.html",
Cr.NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY],
[ /* regression check, but see bug 671204 */
"filename=foo.html",
"filename=foo.html"],
[ /* sanity check */
"attachment; filename=foo.html",
"attachment"],
];
function run_test() {
var mhp = Components.classes["@mozilla.org/network/mime-hdrparam;1"]
.getService(Components.interfaces.nsIMIMEHeaderParam);
var unused = { value : null };
for (var i = 0; i < tests.length; ++i) {
dump("Testing " + tests[i] + "\n");
try {
do_check_eq(mhp.getParameter(tests[i][0], "", "UTF-8", true, unused),
tests[i][1]);
}
catch (e) {
do_check_eq(e.result, tests[i][1]);
}
}
}

View File

@ -1,24 +0,0 @@
/**
* Test for bug 419157: ensure that a MIME parameter with no charset information
* fallbacks to Latin-1
*/
const Cc = Components.classes;
const Ci = Components.interfaces;
const header = "Content-Disposition: attachment;filename=IT839\x04\xB5(m8)2.pdf;";
const expected = "IT839\u0004\u00b5(m8)2.pdf";
function run_test()
{
var mhp = Cc["@mozilla.org/network/mime-hdrparam;1"].
getService(Ci.nsIMIMEHeaderParam);
var unused = { value : null };
var result = null;
try {
result = mhp.getParameter(header, "filename", "UTF-8", true, unused);
} catch (e) {}
do_check_eq(result, expected);
}

View File

@ -1,39 +0,0 @@
/**
* Test for bug 588389: unescaping backslashes in quoted string parameters
*/
var BS = '\\';
var DQUOTE = '"';
var reference = [
[ // '\"', should be parsed as '"'
"Content-Disposition: attachment; foobar=" + DQUOTE + (BS + DQUOTE) + DQUOTE,
DQUOTE],
[ // 'a\"b', should be parsed as 'a"b'
"Content-Disposition: attachment; foobar=" + DQUOTE + 'a' + (BS + DQUOTE) + 'b' + DQUOTE,
'a' + DQUOTE + 'b'],
[ // '\x', should be parsed as 'x'
"Content-Disposition: attachment; foobar=" + DQUOTE + (BS + "x") + DQUOTE,
"x"],
[ // test empty param (quoted-string)
"Content-Disposition: attachment; foobar=" + DQUOTE + DQUOTE,
""],
[ // test empty param
"Content-Disposition: attachment; foobar=",
""],
];
function run_test() {
var mhp = Components.classes["@mozilla.org/network/mime-hdrparam;1"]
.getService(Components.interfaces.nsIMIMEHeaderParam);
var unused = { value : null };
for (var i = 0; i < reference.length; ++i) {
dump("Testing " + reference[i] + "\n");
do_check_eq(mhp.getParameter(reference[i][0], "foobar", "UTF-8", true, unused),
reference[i][1]);
}
}

View File

@ -1,37 +0,0 @@
/**
* Test for bug 651185: double quotes around 2231/5987 encoded param
*/
const Cr = Components.results
var BS = '\\';
var DQUOTE = '"';
var tests = [
[ /* sanity check */
"Content-Disposition: attachment; filename*=utf-8''%41",
"A"],
[ /* the actual bug */
"Content-Disposition: attachment; filename*=" + DQUOTE + "utf-8''%41" + DQUOTE,
Cr.NS_ERROR_INVALID_ARG],
];
function run_test() {
var mhp = Components.classes["@mozilla.org/network/mime-hdrparam;1"]
.getService(Components.interfaces.nsIMIMEHeaderParam);
var unused = { value : null };
for (var i = 0; i < tests.length; ++i) {
dump("Testing " + tests[i] + "\n");
try {
do_check_eq(mhp.getParameter(tests[i][0], "filename", "UTF-8", true, unused),
tests[i][1]);
}
catch (e) {
do_check_eq(e.result, tests[i][1]);
}
}
}

View File

@ -1,43 +0,0 @@
/**
* Test for bug 670333: Content-Disposition parser does not require presence of "=" in params
*/
const Cr = Components.results
var BS = '\\';
var DQUOTE = '"';
var tests = [
[ /* sanity check */
"Content-Disposition: attachment; filename*=UTF-8''foo-%41.html",
"foo-A.html"],
[ /* the actual bug */
"Content-Disposition: attachment; filename *=UTF-8''foo-%41.html",
Cr.NS_ERROR_INVALID_ARG],
[ /* the actual bug, without 2231/5987 encoding */
"Content-Disposition: attachment; filename X",
Cr.NS_ERROR_INVALID_ARG],
[ /* sanity check with WS on both sides */
"Content-Disposition: attachment; filename = foo-A.html",
"foo-A.html"],
];
function run_test() {
var mhp = Components.classes["@mozilla.org/network/mime-hdrparam;1"]
.getService(Components.interfaces.nsIMIMEHeaderParam);
var unused = { value : null };
for (var i = 0; i < tests.length; ++i) {
dump("Testing " + tests[i] + "\n");
try {
do_check_eq(mhp.getParameter(tests[i][0], "filename", "UTF-8", true, unused),
tests[i][1]);
}
catch (e) {
do_check_eq(e.result, tests[i][1]);
}
}
}

View File

@ -16,7 +16,6 @@ skip-if = os == "android"
[test_bug248970_cookie.js]
[test_bug261425.js]
[test_bug263127.js]
[test_bug272541.js]
[test_bug321706.js]
[test_bug331825.js]
[test_bug336501.js]
@ -35,7 +34,6 @@ skip-if = os == "android"
[test_bug411952.js]
[test_bug412945.js]
[test_bug414122.js]
[test_bug419157.js]
[test_bug427957.js]
[test_bug429347.js]
[test_bug455311.js]
@ -63,7 +61,6 @@ skip-if = os == "android"
[test_bug561276.js]
[test_bug580508.js]
[test_bug586908.js]
[test_bug588389.js]
[test_bug596443.js]
[test_bug618835.js]
[test_bug633743.js]
@ -83,9 +80,7 @@ fail-if = os == "android"
fail-if = os == "android"
[test_bug659569.js]
[test_bug660066.js]
[test_bug651185.js]
[test_bug667907.js]
[test_bug670333.js]
[test_bug667818.js]
[test_cacheflags.js]
[test_channel_close.js]