r=gagan. 29870. We weren't handling a malformed http-equiv refresh header.

This commit is contained in:
valeski%netscape.com 2000-03-04 00:32:30 +00:00
parent 4aa93745ce
commit 942c0cbea5
2 changed files with 212 additions and 94 deletions

View File

@ -3760,65 +3760,124 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
// <META HTTP-EQUIV=REFRESH CONTENT="5; URL=http://uri"> // <META HTTP-EQUIV=REFRESH CONTENT="5; URL=http://uri">
// By the time we are here, the following is true: // By the time we are here, the following is true:
// header = "REFRESH" // header = "REFRESH"
// result = "5; URL=http://uri" // note the URL attribute is optional, if it // result = "5; URL=http://uri" // note the URL attribute is
// is absent, the currently loaded url is used. // optional, if it is absent, the currently loaded url is used.
const PRUnichar *uriCStr = nsnull; //
nsAutoString uriAttribStr; // We need to handle the following strings.
// - X is a set of digits
// - URI is either a relative or absolute URI
// - FOO is any text
//
// ""
// empty string. use the currently loaded URI
// and refresh immediately.
// "X"
// Refresh the currently loaded URI in X milliseconds.
// "X; URI"
// Refresh using URI as the destination in X milliseconds.
// "X; URI; Blah"
// Refresh using URI as the destination in X milliseconds,
// ignoring "Blah"
// "URI"
// Refresh immediately using URI as the destination.
// "URI; Blah"
// Refresh immediately using URI as the destination,
// ignoring "Blah"
//
// Note that we need to remove any tokens wrapping the URI.
// These tokens currently include spaces, double and single
// quotes.
// first get our baseURI // first get our baseURI
rv = mWebShell->GetURL(&uriCStr); const PRUnichar *loadedURI = nsnull;
rv = mWebShell->GetURL(&loadedURI);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> baseURI; nsCOMPtr<nsIURI> baseURI;
rv = NS_NewURI(getter_AddRefs(baseURI), uriCStr, nsnull); rv = NS_NewURI(getter_AddRefs(baseURI), loadedURI, nsnull);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
// next get any uri provided as an attribute in the tag. PRInt32 millis = -1;
PRInt32 loc = result.Find("url", PR_TRUE); PRUnichar *uriAttrib = nsnull;
PRInt32 urlLoc = loc;
if (loc > -1) { PRInt32 semiColon = result.FindChar(';');
// there is a url attribute, let's use it. nsAutoString token;
loc += 3; if (semiColon > -1)
// go past the '=' sign result.Left(token, semiColon);
loc = result.Find("=", PR_TRUE, loc); else
if (loc > -1) { token = result;
loc++;
result.Mid(uriAttribStr, loc, result.Length() - loc); PRBool done = PR_FALSE;
uriAttribStr.CompressWhitespace(); while (!done && !token.IsEmpty()) {
// remove any single or double quotes from the ends of the string token.CompressWhitespace();
uriAttribStr.Trim("\"'"); if (millis == -1 && nsString::IsDigit(token.First())) {
uriCStr = uriAttribStr.GetUnicode(); PRInt32 i = 0;
PRUnichar value = nsnull;
while ((value = token[i++])) {
if (!nsString::IsDigit(value)) {
i = -1;
break;
}
}
if (i > -1) {
PRInt32 err;
millis = token.ToInteger(&err) * 1000;
} else {
done = PR_TRUE;
}
} else {
done = PR_TRUE;
} }
} if (done) {
PRInt32 loc = token.FindChar('=');
if (loc > -1)
token.Cut(0, loc+1);
token.Trim(" \"'");
uriAttrib = token.ToNewUnicode();
} else {
// Increment to the next token.
if (semiColon > -1) {
semiColon++;
PRInt32 semiColon2 = result.FindChar(';', PR_FALSE, semiColon);
if (semiColon2 == -1) semiColon2 = result.Length();
result.Mid(token, semiColon, semiColon2 - semiColon);
semiColon = semiColon2;
} else {
done = PR_TRUE;
}
}
} // end while
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), uriCStr, baseURI); if (!uriAttrib) {
if (loc > -1 && NS_SUCCEEDED(rv)) { uri = baseURI;
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_SUCCEEDED(rv))
rv = securityManager->CheckLoadURI(baseURI, uri,
PR_TRUE);
}
if (NS_FAILED(rv)) return rv;
// the units of the numeric value contained in the result are seconds.
// we need them in milliseconds before handing off to the refresh interface.
PRInt32 millis;
if (urlLoc > 1) {
nsString2 seconds;
result.Left(seconds, urlLoc-1);
millis = seconds.ToInteger(&loc) * 1000;
} else { } else {
millis = result.ToInteger(&loc) * 1000; rv = NS_NewURI(getter_AddRefs(uri), uriAttrib, baseURI);
nsAllocator::Free(uriAttrib);
} }
nsCOMPtr<nsIRefreshURI> reefer = do_QueryInterface(mWebShell, &rv); if (NS_SUCCEEDED(rv)) {
if (NS_FAILED(rv)) return rv; NS_WITH_SERVICE(nsIScriptSecurityManager,
securityManager,
rv = reefer->RefreshURI(uri, millis, PR_FALSE); NS_SCRIPTSECURITYMANAGER_PROGID,
if (NS_FAILED(rv)) return rv; &rv);
if (NS_SUCCEEDED(rv)) {
rv = securityManager->CheckLoadURI(baseURI,
uri,
PR_TRUE);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIRefreshURI> reefer =
do_QueryInterface(mWebShell);
if (reefer) {
if (millis == -1) millis = 0;
rv = reefer->RefreshURI(uri, millis,
PR_FALSE);
if (NS_FAILED(rv)) return rv;
}
}
}
}
} // END refresh } // END refresh
else if (!header.Compare("set-cookie", PR_TRUE)) { else if (!header.Compare("set-cookie", PR_TRUE)) {
nsCOMPtr<nsICookieService> cookieServ = do_GetService(NS_COOKIESERVICE_PROGID, &rv); nsCOMPtr<nsICookieService> cookieServ = do_GetService(NS_COOKIESERVICE_PROGID, &rv);

View File

@ -3760,65 +3760,124 @@ HTMLContentSink::ProcessMETATag(const nsIParserNode& aNode)
// <META HTTP-EQUIV=REFRESH CONTENT="5; URL=http://uri"> // <META HTTP-EQUIV=REFRESH CONTENT="5; URL=http://uri">
// By the time we are here, the following is true: // By the time we are here, the following is true:
// header = "REFRESH" // header = "REFRESH"
// result = "5; URL=http://uri" // note the URL attribute is optional, if it // result = "5; URL=http://uri" // note the URL attribute is
// is absent, the currently loaded url is used. // optional, if it is absent, the currently loaded url is used.
const PRUnichar *uriCStr = nsnull; //
nsAutoString uriAttribStr; // We need to handle the following strings.
// - X is a set of digits
// - URI is either a relative or absolute URI
// - FOO is any text
//
// ""
// empty string. use the currently loaded URI
// and refresh immediately.
// "X"
// Refresh the currently loaded URI in X milliseconds.
// "X; URI"
// Refresh using URI as the destination in X milliseconds.
// "X; URI; Blah"
// Refresh using URI as the destination in X milliseconds,
// ignoring "Blah"
// "URI"
// Refresh immediately using URI as the destination.
// "URI; Blah"
// Refresh immediately using URI as the destination,
// ignoring "Blah"
//
// Note that we need to remove any tokens wrapping the URI.
// These tokens currently include spaces, double and single
// quotes.
// first get our baseURI // first get our baseURI
rv = mWebShell->GetURL(&uriCStr); const PRUnichar *loadedURI = nsnull;
rv = mWebShell->GetURL(&loadedURI);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> baseURI; nsCOMPtr<nsIURI> baseURI;
rv = NS_NewURI(getter_AddRefs(baseURI), uriCStr, nsnull); rv = NS_NewURI(getter_AddRefs(baseURI), loadedURI, nsnull);
if (NS_FAILED(rv)) return rv; if (NS_FAILED(rv)) return rv;
// next get any uri provided as an attribute in the tag. PRInt32 millis = -1;
PRInt32 loc = result.Find("url", PR_TRUE); PRUnichar *uriAttrib = nsnull;
PRInt32 urlLoc = loc;
if (loc > -1) { PRInt32 semiColon = result.FindChar(';');
// there is a url attribute, let's use it. nsAutoString token;
loc += 3; if (semiColon > -1)
// go past the '=' sign result.Left(token, semiColon);
loc = result.Find("=", PR_TRUE, loc); else
if (loc > -1) { token = result;
loc++;
result.Mid(uriAttribStr, loc, result.Length() - loc); PRBool done = PR_FALSE;
uriAttribStr.CompressWhitespace(); while (!done && !token.IsEmpty()) {
// remove any single or double quotes from the ends of the string token.CompressWhitespace();
uriAttribStr.Trim("\"'"); if (millis == -1 && nsString::IsDigit(token.First())) {
uriCStr = uriAttribStr.GetUnicode(); PRInt32 i = 0;
PRUnichar value = nsnull;
while ((value = token[i++])) {
if (!nsString::IsDigit(value)) {
i = -1;
break;
}
}
if (i > -1) {
PRInt32 err;
millis = token.ToInteger(&err) * 1000;
} else {
done = PR_TRUE;
}
} else {
done = PR_TRUE;
} }
} if (done) {
PRInt32 loc = token.FindChar('=');
if (loc > -1)
token.Cut(0, loc+1);
token.Trim(" \"'");
uriAttrib = token.ToNewUnicode();
} else {
// Increment to the next token.
if (semiColon > -1) {
semiColon++;
PRInt32 semiColon2 = result.FindChar(';', PR_FALSE, semiColon);
if (semiColon2 == -1) semiColon2 = result.Length();
result.Mid(token, semiColon, semiColon2 - semiColon);
semiColon = semiColon2;
} else {
done = PR_TRUE;
}
}
} // end while
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), uriCStr, baseURI); if (!uriAttrib) {
if (loc > -1 && NS_SUCCEEDED(rv)) { uri = baseURI;
NS_WITH_SERVICE(nsIScriptSecurityManager, securityManager,
NS_SCRIPTSECURITYMANAGER_PROGID, &rv);
if (NS_SUCCEEDED(rv))
rv = securityManager->CheckLoadURI(baseURI, uri,
PR_TRUE);
}
if (NS_FAILED(rv)) return rv;
// the units of the numeric value contained in the result are seconds.
// we need them in milliseconds before handing off to the refresh interface.
PRInt32 millis;
if (urlLoc > 1) {
nsString2 seconds;
result.Left(seconds, urlLoc-1);
millis = seconds.ToInteger(&loc) * 1000;
} else { } else {
millis = result.ToInteger(&loc) * 1000; rv = NS_NewURI(getter_AddRefs(uri), uriAttrib, baseURI);
nsAllocator::Free(uriAttrib);
} }
nsCOMPtr<nsIRefreshURI> reefer = do_QueryInterface(mWebShell, &rv); if (NS_SUCCEEDED(rv)) {
if (NS_FAILED(rv)) return rv; NS_WITH_SERVICE(nsIScriptSecurityManager,
securityManager,
rv = reefer->RefreshURI(uri, millis, PR_FALSE); NS_SCRIPTSECURITYMANAGER_PROGID,
if (NS_FAILED(rv)) return rv; &rv);
if (NS_SUCCEEDED(rv)) {
rv = securityManager->CheckLoadURI(baseURI,
uri,
PR_TRUE);
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsIRefreshURI> reefer =
do_QueryInterface(mWebShell);
if (reefer) {
if (millis == -1) millis = 0;
rv = reefer->RefreshURI(uri, millis,
PR_FALSE);
if (NS_FAILED(rv)) return rv;
}
}
}
}
} // END refresh } // END refresh
else if (!header.Compare("set-cookie", PR_TRUE)) { else if (!header.Compare("set-cookie", PR_TRUE)) {
nsCOMPtr<nsICookieService> cookieServ = do_GetService(NS_COOKIESERVICE_PROGID, &rv); nsCOMPtr<nsICookieService> cookieServ = do_GetService(NS_COOKIESERVICE_PROGID, &rv);