Bug 1344461 - Keep track of line length to not read beyond eol. r=valentin a=gchang

--HG--
extra : source : 5ef67e15fd88a16025632e31ec1bb6519d2f4441
This commit is contained in:
Daniel Stenberg 2017-03-20 18:23:18 -04:00
parent ffb0ca0de0
commit 1611182cbc
2 changed files with 43 additions and 16 deletions

View file

@ -154,6 +154,7 @@ nsDirIndexParser::ParseFormat(const char* aFormatStr) {
if (mFormat == nullptr) if (mFormat == nullptr)
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
mFormat[num] = -1; mFormat[num] = -1;
mFormat[0] = -1; // to detect zero header fields
int formatNum=0; int formatNum=0;
do { do {
@ -192,7 +193,8 @@ nsDirIndexParser::ParseFormat(const char* aFormatStr) {
} }
nsresult nsresult
nsDirIndexParser::ParseData(nsIDirIndex *aIdx, char* aDataStr) { nsDirIndexParser::ParseData(nsIDirIndex *aIdx, char* aDataStr, int32_t aLineLen)
{
// Parse a "201" data line, using the field ordering specified in // Parse a "201" data line, using the field ordering specified in
// mFormat. // mFormat.
@ -202,37 +204,62 @@ nsDirIndexParser::ParseData(nsIDirIndex *aIdx, char* aDataStr) {
} }
nsresult rv = NS_OK; nsresult rv = NS_OK;
nsAutoCString filename; nsAutoCString filename;
int32_t lineLen = aLineLen;
if (mFormat[0] == -1) {
// no known header fields is an error
return NS_ERROR_ILLEGAL_VALUE;
}
for (int32_t i = 0; mFormat[i] != -1; ++i) { for (int32_t i = 0; mFormat[i] != -1; ++i) {
// If we've exhausted the data before we run out of fields, just // If we've exhausted the data before we run out of fields, just bail.
// bail. if (!*aDataStr || (lineLen < 1)) {
if (! *aDataStr) return NS_ERROR_ILLEGAL_VALUE;
break; }
while (*aDataStr && nsCRT::IsAsciiSpace(*aDataStr)) while ((lineLen > 0) && nsCRT::IsAsciiSpace(*aDataStr)) {
++aDataStr; ++aDataStr;
--lineLen;
}
if (lineLen < 1) {
// invalid format, bail
return NS_ERROR_ILLEGAL_VALUE;
}
char *value = aDataStr; char *value = aDataStr;
if (*aDataStr == '"' || *aDataStr == '\'') { if (*aDataStr == '"' || *aDataStr == '\'') {
// it's a quoted string. snarf everything up to the next quote character // it's a quoted string. snarf everything up to the next quote character
const char quotechar = *(aDataStr++); const char quotechar = *(aDataStr++);
lineLen--;
++value; ++value;
while (*aDataStr && *aDataStr != quotechar) while ((lineLen > 0) && *aDataStr != quotechar) {
++aDataStr; ++aDataStr;
--lineLen;
}
if (lineLen > 0) {
*aDataStr++ = '\0'; *aDataStr++ = '\0';
--lineLen;
}
if (! aDataStr) { if (!lineLen) {
NS_WARNING("quoted value not terminated"); // invalid format, bail
return NS_ERROR_ILLEGAL_VALUE;
} }
} else { } else {
// it's unquoted. snarf until we see whitespace. // it's unquoted. snarf until we see whitespace.
value = aDataStr; value = aDataStr;
while (*aDataStr && (!nsCRT::IsAsciiSpace(*aDataStr))) while ((lineLen > 0) && (!nsCRT::IsAsciiSpace(*aDataStr))) {
++aDataStr; ++aDataStr;
--lineLen;
}
if (lineLen > 0) {
*aDataStr++ = '\0'; *aDataStr++ = '\0';
--lineLen;
}
// even if we ran out of line length here, there's still a trailing zero
// byte afterwards
} }
fieldType t = fieldType(mFormat[i]); fieldType t = fieldType(mFormat[i]);
@ -404,7 +431,7 @@ nsDirIndexParser::ProcessData(nsIRequest *aRequest, nsISupports *aCtxt) {
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
rv = ParseData(idx, ((char *)buf) + 4); rv = ParseData(idx, ((char *)buf) + 4, lineLen - 4);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return rv; return rv;
} }

View file

@ -51,7 +51,7 @@ protected:
nsresult ProcessData(nsIRequest *aRequest, nsISupports *aCtxt); nsresult ProcessData(nsIRequest *aRequest, nsISupports *aCtxt);
nsresult ParseFormat(const char* buf); nsresult ParseFormat(const char* buf);
nsresult ParseData(nsIDirIndex* aIdx, char* aDataStr); nsresult ParseData(nsIDirIndex* aIdx, char* aDataStr, int32_t lineLen);
struct Field { struct Field {
const char *mName; const char *mName;