From fe2e02be609856ef891359e82a6dbeb77771d9d7 Mon Sep 17 00:00:00 2001 From: Michal Novotny Date: Wed, 23 Sep 2009 02:15:29 +0200 Subject: [PATCH] Bug 515583 - Fixed parsing of CMU/VMS-IP FTP style listing [r=dougt r=wtc sr=biesi] --- .../streamconv/converters/ParseFTPList.cpp | 26 +++++-- netwerk/test/unit/test_bug515583.js | 72 +++++++++++++++++++ 2 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 netwerk/test/unit/test_bug515583.js diff --git a/netwerk/streamconv/converters/ParseFTPList.cpp b/netwerk/streamconv/converters/ParseFTPList.cpp index 8a19b80ca8c6..d9b20275719f 100644 --- a/netwerk/streamconv/converters/ParseFTPList.cpp +++ b/netwerk/streamconv/converters/ParseFTPList.cpp @@ -40,11 +40,19 @@ #include #include #include "plstr.h" +#include "nsDebug.h" #include "ParseFTPList.h" /* ==================================================================== */ +static inline int ParseFTPListDetermineRetval(struct list_state *state) +{ + if (state->parsed_one || state->lstyle) /* junk if we fail to parse */ + return '?'; /* this time but had previously parsed successfully */ + return '"'; /* its part of a comment or error message */ +} + int ParseFTPList(const char *line, struct list_state *state, struct list_result *result ) { @@ -123,6 +131,9 @@ int ParseFTPList(const char *line, struct list_state *state, } } + if (!numtoks) + return ParseFTPListDetermineRetval(state); + linelen_sans_wsp = &(tokens[numtoks-1][toklen[numtoks-1]]) - tokens[0]; if (numtoks == (sizeof(tokens)/sizeof(tokens[0])) ) { @@ -356,11 +367,16 @@ int ParseFTPList(const char *line, struct list_state *state, pos++; p++; } - if (lstyle && pos < (toklen[0]-1) && *p == ']') + if (lstyle && pos < (toklen[0]-1)) { + /* ']' was found and there is at least one character after it */ + NS_ASSERTION(*p == ']', "unexpected state"); pos++; p++; tokmarker = pos; /* length of leading "[DIR1.DIR2.etc]" */ + } else { + /* not a CMU style listing */ + lstyle = 0; } } while (lstyle && pos < toklen[0] && *p != ';') @@ -387,7 +403,7 @@ int ParseFTPList(const char *line, struct list_state *state, pos -= tokmarker; /* => fnlength sans "[DIR1.DIR2.etc]" */ p = &(tokens[0][tokmarker]); /* offset of basename */ - if (!lstyle || pos > 80) /* VMS filenames can't be longer than that */ + if (!lstyle || pos == 0 || pos > 80) /* VMS filenames can't be longer than that */ { lstyle = 0; } @@ -1684,9 +1700,7 @@ int ParseFTPList(const char *line, struct list_state *state, } /* if (linelen > 0) */ - if (state->parsed_one || state->lstyle) /* junk if we fail to parse */ - return '?'; /* this time but had previously parsed successfully */ - return '"'; /* its part of a comment or error message */ + return ParseFTPListDetermineRetval(state); } /* ==================================================================== */ @@ -1705,7 +1719,7 @@ static int do_it(FILE *outfile, char *p; int rc; - rc = ParseFTPLIST( line, state, &result ); + rc = ParseFTPList( line, state, &result ); if (!outfile) { diff --git a/netwerk/test/unit/test_bug515583.js b/netwerk/test/unit/test_bug515583.js new file mode 100644 index 000000000000..2fea545e0978 --- /dev/null +++ b/netwerk/test/unit/test_bug515583.js @@ -0,0 +1,72 @@ +function getURLContent(aURL) { + var ios = Components.classes["@mozilla.org/network/io-service;1"]. + getService(Components.interfaces.nsIIOService); + + var uri = ios.newURI(aURL, null, null); + var chan = ios.newChannelFromURI(uri); + var inp = chan.open(); + var scinp = Components.classes["@mozilla.org/scriptableinputstream;1"]. + createInstance(Components.interfaces.nsIScriptableInputStream); + scinp.init(inp); + var result = ""; + var avail = scinp.available(); + while (avail) { + result += scinp.read(avail); + avail = scinp.available(); + } + return result; +} + +function storeCache(aURL, aContent) { + const nsICache = Components.interfaces.nsICache; + + var cache = Components.classes["@mozilla.org/network/cache-service;1"]. + getService(Components.interfaces.nsICacheService); + + var session = cache.createSession("FTP", nsICache.STORE_ANYWHERE, nsICache.STREAM_BASED); + + var cacheEntry = session.openCacheEntry(aURL, nsICache.ACCESS_READ_WRITE, false); + + cacheEntry.setMetaDataElement("servertype", "0"); + var oStream = cacheEntry.openOutputStream(0); + + var written = oStream.write(aContent, aContent.length); + if (written != aContent.length) { + do_throw("oStream.write has not written all data!\n" + + " Expected: " + written + "\n" + + " Actual: " + aContent.length + "\n"); + } + oStream.close(); + cacheEntry.close(); +} + +const URL = "ftp://localhost/bug515583/"; + +const tests = [ + ["[RWCEM1 4 1-MAR-1993 18:09:01.12\r\n" + + "[RWCEM1] 4 2-MAR-1993 18:09:01.12\r\n" + + "[RWCEM1]A 4 3-MAR-1993 18:09:01.12\r\n" + + "[RWCEM1]B; 4 4-MAR-1993 18:09:01.12\r\n" + + "[RWCEM1];1 4 5-MAR-1993 18:09:01.12\r\n" + + "[RWCEM1]; 4 6-MAR-1993 18:09:01.12\r\n" + + "[RWCEM1]C;1D 4 7-MAR-1993 18:09:01.12\r\n" + + "[RWCEM1]E;1 4 8-MAR-1993 18:09:01.12\r\n" + , + "300: " + URL + "\n" + + "200: filename content-length last-modified file-type\n" + + "201: \"A\" 2048 Sun%2C%2003%20Mar%201993%2018%3A09%3A01 FILE \n" + + "201: \"E\" 2048 Sun%2C%2008%20Mar%201993%2018%3A09%3A01 FILE \n"] + , + ["\r\r\r\n" + , + "300: " + URL + "\n" + + "200: filename content-length last-modified file-type\n"] +] + +function run_test() { + for (var i = 0; i < tests.length; i++) { + storeCache(URL, tests[i][0]); + var parsedData = getURLContent(URL); + do_check_eq(parsedData, tests[i][1]); + } +}