LCOV - app.info - docshell/base/nsDefaultURIFixup.cpp

LCOV - code coverage report
| Current view: | directory - docshell/base - nsDefaultURIFixup.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 324 | 76 | 23.5 %
| Date: | 2012-04-21 | Functions: | 19 | 10 | 52.6 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  *
           3                 :  * ***** BEGIN LICENSE BLOCK *****
           4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           5                 :  *
           6                 :  * The contents of this file are subject to the Mozilla Public License Version
           7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           8                 :  * the License. You may obtain a copy of the License at
           9                 :  * http://www.mozilla.org/MPL/
          10                 :  *
          11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          13                 :  * for the specific language governing rights and limitations under the
          14                 :  * License.
          15                 :  *
          16                 :  * The Original Code is the Mozilla browser.
          17                 :  *
          18                 :  * The Initial Developer of the Original Code is
          19                 :  * Netscape Communications, Inc.
          20                 :  * Portions created by the Initial Developer are Copyright (C) 1999
          21                 :  * the Initial Developer. All Rights Reserved.
          22                 :  *
          23                 :  * Contributor(s):
          24                 :  *   Adam Lock <adamlock@netscape.com>
          25                 :  *   Jeff Walden <jwalden+code@mit.edu>
          26                 :  *
          27                 :  * Alternatively, the contents of this file may be used under the terms of
          28                 :  * either of the GNU General Public License Version 2 or later (the "GPL"),
          29                 :  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          31                 :  * of those above. If you wish to allow use of your version of this file only
          32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          33                 :  * use your version of this file under the terms of the MPL, indicate your
          34                 :  * decision by deleting the provisions above and replace them with the notice
          35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          36                 :  * the provisions above, a recipient may use your version of this file under
          37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          38                 :  *
          39                 :  * ***** END LICENSE BLOCK ***** */
          40                 :
          41                 : #include "nsString.h"
          42                 : #include "nsReadableUtils.h"
          43                 : #include "nsNetUtil.h"
          44                 : #include "nsEscape.h"
          45                 : #include "nsCRT.h"
          46                 :
          47                 : #include "nsIPlatformCharset.h"
          48                 : #include "nsILocalFile.h"
          49                 :
          50                 : #ifdef MOZ_TOOLKIT_SEARCH
          51                 : #include "nsIBrowserSearchService.h"
          52                 : #endif
          53                 :
          54                 : #include "nsIURIFixup.h"
          55                 : #include "nsDefaultURIFixup.h"
          56                 : #include "mozilla/Preferences.h"
          57                 :
          58                 : using namespace mozilla;
          59                 :
          60                 : /* Implementation file */
          61               9 : NS_IMPL_ISUPPORTS1(nsDefaultURIFixup, nsIURIFixup)
          62                 :
          63               1 : nsDefaultURIFixup::nsDefaultURIFixup()
          64                 : {
          65                 :   /* member initializers and constructor code */
          66               1 : }
          67                 :
          68                 :
          69               2 : nsDefaultURIFixup::~nsDefaultURIFixup()
          70                 : {
          71                 :   /* destructor code */
          72               4 : }
          73                 :
          74                 : /* nsIURI createExposableURI (in nsIRUI aURI); */
          75                 : NS_IMETHODIMP
          76               0 : nsDefaultURIFixup::CreateExposableURI(nsIURI *aURI, nsIURI **aReturn)
          77                 : {
          78               0 :     NS_ENSURE_ARG_POINTER(aURI);
          79               0 :     NS_ENSURE_ARG_POINTER(aReturn);
          80                 :
          81               0 :     bool isWyciwyg = false;
          82               0 :     aURI->SchemeIs("wyciwyg", &isWyciwyg);
          83                 :
          84               0 :     nsCAutoString userPass;
          85               0 :     aURI->GetUserPass(userPass);
          86                 :
          87                 :     // most of the time we can just AddRef and return
          88               0 :     if (!isWyciwyg && userPass.IsEmpty())
          89                 :     {
          90               0 :         *aReturn = aURI;
          91               0 :         NS_ADDREF(*aReturn);
          92               0 :         return NS_OK;
          93                 :     }
          94                 :
          95                 :     // Rats, we have to massage the URI
          96               0 :     nsCOMPtr<nsIURI> uri;
          97               0 :     if (isWyciwyg)
          98                 :     {
          99               0 :         nsCAutoString path;
         100               0 :         nsresult rv = aURI->GetPath(path);
         101               0 :         NS_ENSURE_SUCCESS(rv, rv);
         102                 :
         103               0 :         PRUint32 pathLength = path.Length();
         104               0 :         if (pathLength <= 2)
         105                 :         {
         106               0 :             return NS_ERROR_FAILURE;
         107                 :         }
         108                 :
         109                 :         // Path is of the form "//123/http://foo/bar", with a variable number of digits.
         110                 :         // To figure out where the "real" URL starts, search path for a '/', starting at
         111                 :         // the third character.
         112               0 :         PRInt32 slashIndex = path.FindChar('/', 2);
         113               0 :         if (slashIndex == kNotFound)
         114                 :         {
         115               0 :             return NS_ERROR_FAILURE;
         116                 :         }
         117                 :
         118                 :         // Get the charset of the original URI so we can pass it to our fixed up URI.
         119               0 :         nsCAutoString charset;
         120               0 :         aURI->GetOriginCharset(charset);
         121                 :
         122               0 :         rv = NS_NewURI(getter_AddRefs(uri),
         123               0 :                    Substring(path, slashIndex + 1, pathLength - slashIndex - 1),
         124               0 :                    charset.get());
         125               0 :         NS_ENSURE_SUCCESS(rv, rv);
         126                 :     }
         127                 :     else
         128                 :     {
         129                 :         // clone the URI so zapping user:pass doesn't change the original
         130               0 :         nsresult rv = aURI->Clone(getter_AddRefs(uri));
         131               0 :         NS_ENSURE_SUCCESS(rv, rv);
         132                 :     }
         133                 :
         134                 :     // hide user:pass unless overridden by pref
         135               0 :     if (Preferences::GetBool("browser.fixup.hide_user_pass", true))
         136                 :     {
         137               0 :         uri->SetUserPass(EmptyCString());
         138                 :     }
         139                 :
         140                 :     // return the fixed-up URI
         141               0 :     *aReturn = uri;
         142               0 :     NS_ADDREF(*aReturn);
         143               0 :     return NS_OK;
         144                 : }
         145                 :
         146                 : /* nsIURI createFixupURI (in nsAUTF8String aURIText, in unsigned long aFixupFlags); */
         147                 : NS_IMETHODIMP
         148               4 : nsDefaultURIFixup::CreateFixupURI(const nsACString& aStringURI, PRUint32 aFixupFlags, nsIURI **aURI)
         149                 : {
         150               4 :     NS_ENSURE_ARG(!aStringURI.IsEmpty());
         151               4 :     NS_ENSURE_ARG_POINTER(aURI);
         152                 :
         153                 :     nsresult rv;
         154               4 :     *aURI = nsnull;
         155                 :
         156               8 :     nsCAutoString uriString(aStringURI);
         157               4 :     uriString.Trim(" ");  // Cleanup the empty spaces that might be on each end.
         158                 :
         159                 :     // Eliminate embedded newlines, which single-line text fields now allow:
         160               4 :     uriString.StripChars("\r\n");
         161                 :
         162               4 :     NS_ENSURE_TRUE(!uriString.IsEmpty(), NS_ERROR_FAILURE);
         163                 :
         164               8 :     nsCOMPtr<nsIIOService> ioService = do_GetService(NS_IOSERVICE_CONTRACTID, &rv);
         165               4 :     NS_ENSURE_SUCCESS(rv, rv);
         166               8 :     nsCAutoString scheme;
         167               4 :     ioService->ExtractScheme(aStringURI, scheme);
         168                 :
         169                 :     // View-source is a pseudo scheme. We're interested in fixing up the stuff
         170                 :     // after it. The easiest way to do that is to call this method again with the
         171                 :     // "view-source:" lopped off and then prepend it again afterwards.
         172                 :
         173               4 :     if (scheme.LowerCaseEqualsLiteral("view-source"))
         174                 :     {
         175               0 :         nsCOMPtr<nsIURI> uri;
         176               0 :         PRUint32 newFixupFlags = aFixupFlags & ~FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP;
         177                 :
         178                 :         rv =  CreateFixupURI(Substring(uriString,
         179                 :                                        sizeof("view-source:") - 1,
         180               0 :                                        uriString.Length() -
         181               0 :                                          (sizeof("view-source:") - 1)),
         182               0 :                              newFixupFlags, getter_AddRefs(uri));
         183               0 :         if (NS_FAILED(rv))
         184               0 :             return NS_ERROR_FAILURE;
         185               0 :         nsCAutoString spec;
         186               0 :         uri->GetSpec(spec);
         187               0 :         uriString.Assign(NS_LITERAL_CSTRING("view-source:") + spec);
         188                 :     }
         189                 :     else {
         190                 :         // Check for if it is a file URL
         191               4 :         FileURIFixup(uriString, aURI);
         192               4 :         if(*aURI)
         193               0 :             return NS_OK;
         194                 :
         195                 : #if defined(XP_WIN) || defined(XP_OS2)
         196                 :         // Not a file URL, so translate '\' to '/' for convenience in the common protocols
         197                 :         // e.g. catch
         198                 :         //
         199                 :         //   http:\\broken.com\address
         200                 :         //   http:\\broken.com/blah
         201                 :         //   broken.com\blah
         202                 :         //
         203                 :         // Code will also do partial fix up the following urls
         204                 :         //
         205                 :         //   http:\\broken.com\address/somewhere\image.jpg (stops at first forward slash)
         206                 :         //   http:\\broken.com\blah?arg=somearg\foo.jpg (stops at question mark)
         207                 :         //   http:\\broken.com#odd\ref (stops at hash)
         208                 :         //
         209                 :         if (scheme.IsEmpty() ||
         210                 :             scheme.LowerCaseEqualsLiteral("http") ||
         211                 :             scheme.LowerCaseEqualsLiteral("https") ||
         212                 :             scheme.LowerCaseEqualsLiteral("ftp"))
         213                 :         {
         214                 :             // Walk the string replacing backslashes with forward slashes until
         215                 :             // the end is reached, or a question mark, or a hash, or a forward
         216                 :             // slash. The forward slash test is to stop before trampling over
         217                 :             // URIs which legitimately contain a mix of both forward and
         218                 :             // backward slashes.
         219                 :             nsCAutoString::iterator start;
         220                 :             nsCAutoString::iterator end;
         221                 :             uriString.BeginWriting(start);
         222                 :             uriString.EndWriting(end);
         223                 :             while (start != end) {
         224                 :                 if (*start == '?' || *start == '#' || *start == '/')
         225                 :                     break;
         226                 :                 if (*start == '\\')
         227                 :                     *start = '/';
         228                 :                 ++start;
         229                 :             }
         230                 :         }
         231                 : #endif
         232                 :     }
         233                 :
         234                 :     // For these protocols, use system charset instead of the default UTF-8,
         235                 :     // if the URI is non ASCII.
         236               4 :     bool bAsciiURI = IsASCII(uriString);
         237                 :     bool useUTF8 = (aFixupFlags & FIXUP_FLAG_USE_UTF8) ||
         238               4 :                    Preferences::GetBool("browser.fixup.use-utf8", false);
         239                 :     bool bUseNonDefaultCharsetForURI =
         240               4 :                         !bAsciiURI && !useUTF8 &&
         241               0 :                         (scheme.IsEmpty() ||
         242               0 :                          scheme.LowerCaseEqualsLiteral("http") ||
         243               0 :                          scheme.LowerCaseEqualsLiteral("https") ||
         244               0 :                          scheme.LowerCaseEqualsLiteral("ftp") ||
         245               4 :                          scheme.LowerCaseEqualsLiteral("file"));
         246                 :
         247                 :     // Now we need to check whether "scheme" is something we don't
         248                 :     // really know about.
         249               8 :     nsCOMPtr<nsIProtocolHandler> ourHandler, extHandler;
         250                 :
         251               4 :     ioService->GetProtocolHandler(scheme.get(), getter_AddRefs(ourHandler));
         252               4 :     extHandler = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX"default");
         253                 :
         254               4 :     if (ourHandler != extHandler || !PossiblyHostPortUrl(uriString)) {
         255                 :         // Just try to create an URL out of it
         256                 :         rv = NS_NewURI(aURI, uriString,
         257               4 :                        bUseNonDefaultCharsetForURI ? GetCharsetForUrlBar() : nsnull);
         258                 :
         259               4 :         if (!*aURI && rv != NS_ERROR_MALFORMED_URI) {
         260               0 :             return rv;
         261                 :         }
         262                 :     }
         263                 :
         264               4 :     if (*aURI) {
         265               4 :         if (aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI)
         266               2 :             MakeAlternateURI(*aURI);
         267               4 :         return NS_OK;
         268                 :     }
         269                 :
         270                 :     // See if it is a keyword
         271                 :     // Test whether keywords need to be fixed up
         272               0 :     bool fixupKeywords = false;
         273               0 :     if (aFixupFlags & FIXUP_FLAG_ALLOW_KEYWORD_LOOKUP) {
         274               0 :         nsresult rv = Preferences::GetBool("keyword.enabled", &fixupKeywords);
         275               0 :         NS_ENSURE_SUCCESS(rv, NS_ERROR_FAILURE);
         276               0 :         if (fixupKeywords)
         277                 :         {
         278               0 :             KeywordURIFixup(uriString, aURI);
         279               0 :             if(*aURI)
         280               0 :                 return NS_OK;
         281                 :         }
         282                 :     }
         283                 :
         284                 :     // Prune duff protocol schemes
         285                 :     //
         286                 :     //   ://totallybroken.url.com
         287                 :     //   //shorthand.url.com
         288                 :     //
         289               0 :     if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("://")))
         290                 :     {
         291               0 :         uriString = StringTail(uriString, uriString.Length() - 3);
         292                 :     }
         293               0 :     else if (StringBeginsWith(uriString, NS_LITERAL_CSTRING("//")))
         294                 :     {
         295               0 :         uriString = StringTail(uriString, uriString.Length() - 2);
         296                 :     }
         297                 :
         298                 :     // Add ftp:// or http:// to front of url if it has no spec
         299                 :     //
         300                 :     // Should fix:
         301                 :     //
         302                 :     //   no-scheme.com
         303                 :     //   ftp.no-scheme.com
         304                 :     //   ftp4.no-scheme.com
         305                 :     //   no-scheme.com/query?foo=http://www.foo.com
         306                 :     //
         307               0 :     PRInt32 schemeDelim = uriString.Find("://",0);
         308               0 :     PRInt32 firstDelim = uriString.FindCharInSet("/:");
         309               0 :     if (schemeDelim <= 0 ||
         310                 :         (firstDelim != -1 && schemeDelim > firstDelim)) {
         311                 :         // find host name
         312               0 :         PRInt32 hostPos = uriString.FindCharInSet("/:?#");
         313               0 :         if (hostPos == -1)
         314               0 :             hostPos = uriString.Length();
         315                 :
         316                 :         // extract host name
         317               0 :         nsCAutoString hostSpec;
         318               0 :         uriString.Left(hostSpec, hostPos);
         319                 :
         320                 :         // insert url spec corresponding to host name
         321               0 :         if (IsLikelyFTP(hostSpec))
         322               0 :             uriString.Assign(NS_LITERAL_CSTRING("ftp://") + uriString);
         323                 :         else
         324               0 :             uriString.Assign(NS_LITERAL_CSTRING("http://") + uriString);
         325                 :
         326                 :         // For ftp & http, we want to use system charset.
         327               0 :         if (!bAsciiURI && !useUTF8)
         328               0 :           bUseNonDefaultCharsetForURI = true;
         329                 :     } // end if checkprotocol
         330                 :
         331               0 :     rv = NS_NewURI(aURI, uriString, bUseNonDefaultCharsetForURI ? GetCharsetForUrlBar() : nsnull);
         332                 :
         333                 :     // Did the caller want us to try an alternative URI?
         334                 :     // If so, attempt to fixup http://foo into http://www.foo.com
         335                 :
         336               0 :     if (*aURI && aFixupFlags & FIXUP_FLAGS_MAKE_ALTERNATE_URI) {
         337               0 :         MakeAlternateURI(*aURI);
         338                 :     }
         339                 :
         340                 :     // If we still haven't been able to construct a valid URI, try to force a
         341                 :     // keyword match.  This catches search strings with '.' or ':' in them.
         342               0 :     if (!*aURI && fixupKeywords)
         343                 :     {
         344               0 :         KeywordToURI(aStringURI, aURI);
         345               0 :         if(*aURI)
         346               0 :             return NS_OK;
         347                 :     }
         348                 :
         349               0 :     return rv;
         350                 : }
         351                 :
         352               0 : NS_IMETHODIMP nsDefaultURIFixup::KeywordToURI(const nsACString& aKeyword,
         353                 :                                               nsIURI **aURI)
         354                 : {
         355               0 :     *aURI = nsnull;
         356               0 :     NS_ENSURE_STATE(Preferences::GetRootBranch());
         357                 :
         358                 :     // Strip leading "?" and leading/trailing spaces from aKeyword
         359               0 :     nsCAutoString keyword(aKeyword);
         360               0 :     if (StringBeginsWith(keyword, NS_LITERAL_CSTRING("?"))) {
         361               0 :         keyword.Cut(0, 1);
         362                 :     }
         363               0 :     keyword.Trim(" ");
         364                 :
         365               0 :     nsAdoptingCString url = Preferences::GetLocalizedCString("keyword.URL");
         366               0 :     if (!url) {
         367                 :         // Fall back to a non-localized pref, for backwards compat
         368               0 :         url = Preferences::GetCString("keyword.URL");
         369                 :     }
         370                 :
         371                 :     // If the pref is set and non-empty, use it.
         372               0 :     if (!url.IsEmpty()) {
         373                 :         // Escape keyword, then prepend URL
         374               0 :         nsCAutoString spec;
         375               0 :         if (!NS_Escape(keyword, spec, url_XPAlphas)) {
         376               0 :             return NS_ERROR_OUT_OF_MEMORY;
         377                 :         }
         378                 :
         379               0 :         spec.Insert(url, 0);
         380                 :
         381               0 :         return NS_NewURI(aURI, spec);
         382                 :     }
         383                 :
         384                 : #ifdef MOZ_TOOLKIT_SEARCH
         385                 :     // Try falling back to the search service's default search engine
         386               0 :     nsCOMPtr<nsIBrowserSearchService> searchSvc = do_GetService("@mozilla.org/browser/search-service;1");
         387               0 :     if (searchSvc) {
         388               0 :         nsCOMPtr<nsISearchEngine> defaultEngine;
         389               0 :         searchSvc->GetOriginalDefaultEngine(getter_AddRefs(defaultEngine));
         390               0 :         if (defaultEngine) {
         391               0 :             nsCOMPtr<nsISearchSubmission> submission;
         392                 :             // We want to allow default search plugins to specify alternate
         393                 :             // parameters that are specific to keyword searches. For the moment,
         394                 :             // do this by first looking for a magic
         395                 :             // "application/x-moz-keywordsearch" submission type. In the future,
         396                 :             // we should instead use a solution that relies on bug 587780.
         397               0 :             defaultEngine->GetSubmission(NS_ConvertUTF8toUTF16(keyword),
         398               0 :                                          NS_LITERAL_STRING("application/x-moz-keywordsearch"),
         399               0 :                                          getter_AddRefs(submission));
         400                 :             // If getting the special x-moz-keywordsearch submission type failed,
         401                 :             // fall back to the default response type.
         402               0 :             if (!submission) {
         403               0 :                 defaultEngine->GetSubmission(NS_ConvertUTF8toUTF16(keyword),
         404               0 :                                              EmptyString(),
         405               0 :                                              getter_AddRefs(submission));
         406                 :             }
         407                 :
         408               0 :             if (submission) {
         409                 :                 // The submission depends on POST data (i.e. the search engine's
         410                 :                 // "method" is POST), we can't use this engine for keyword
         411                 :                 // searches
         412               0 :                 nsCOMPtr<nsIInputStream> postData;
         413               0 :                 submission->GetPostData(getter_AddRefs(postData));
         414               0 :                 if (postData) {
         415               0 :                     return NS_ERROR_NOT_AVAILABLE;
         416                 :                 }
         417                 :
         418               0 :                 return submission->GetUri(aURI);
         419                 :             }
         420                 :         }
         421                 :     }
         422                 : #endif
         423                 :
         424                 :     // out of options
         425               0 :     return NS_ERROR_NOT_AVAILABLE;
         426                 : }
         427                 :
         428               2 : bool nsDefaultURIFixup::MakeAlternateURI(nsIURI *aURI)
         429                 : {
         430               2 :     if (!Preferences::GetRootBranch())
         431                 :     {
         432               0 :         return false;
         433                 :     }
         434               2 :     if (!Preferences::GetBool("browser.fixup.alternate.enabled", true))
         435                 :     {
         436               0 :         return false;
         437                 :     }
         438                 :
         439                 :     // Code only works for http. Not for any other protocol including https!
         440               2 :     bool isHttp = false;
         441               2 :     aURI->SchemeIs("http", &isHttp);
         442               2 :     if (!isHttp) {
         443               0 :         return false;
         444                 :     }
         445                 :
         446                 :     // Security - URLs with user / password info should NOT be fixed up
         447               4 :     nsCAutoString userpass;
         448               2 :     aURI->GetUserPass(userpass);
         449               2 :     if (!userpass.IsEmpty()) {
         450               0 :         return false;
         451                 :     }
         452                 :
         453               4 :     nsCAutoString oldHost;
         454               4 :     nsCAutoString newHost;
         455               2 :     aURI->GetHost(oldHost);
         456                 :
         457                 :     // Count the dots
         458               2 :     PRInt32 numDots = 0;
         459               2 :     nsReadingIterator<char> iter;
         460               2 :     nsReadingIterator<char> iterEnd;
         461               2 :     oldHost.BeginReading(iter);
         462               2 :     oldHost.EndReading(iterEnd);
         463              34 :     while (iter != iterEnd) {
         464              30 :         if (*iter == '.')
         465               4 :             numDots++;
         466              30 :         ++iter;
         467                 :     }
         468                 :
         469                 :
         470                 :     // Get the prefix and suffix to stick onto the new hostname. By default these
         471                 :     // are www. & .com but they could be any other value, e.g. www. & .org
         472                 :
         473               4 :     nsCAutoString prefix("www.");
         474                 :     nsAdoptingCString prefPrefix =
         475               4 :         Preferences::GetCString("browser.fixup.alternate.prefix");
         476               2 :     if (prefPrefix)
         477                 :     {
         478               2 :         prefix.Assign(prefPrefix);
         479                 :     }
         480                 :
         481               4 :     nsCAutoString suffix(".com");
         482                 :     nsAdoptingCString prefSuffix =
         483               4 :         Preferences::GetCString("browser.fixup.alternate.suffix");
         484               2 :     if (prefSuffix)
         485                 :     {
         486               2 :         suffix.Assign(prefSuffix);
         487                 :     }
         488                 :
         489               2 :     if (numDots == 0)
         490                 :     {
         491               0 :         newHost.Assign(prefix);
         492               0 :         newHost.Append(oldHost);
         493               0 :         newHost.Append(suffix);
         494                 :     }
         495               2 :     else if (numDots == 1)
         496                 :     {
         497               0 :         if (!prefix.IsEmpty() &&
         498               0 :                 oldHost.EqualsIgnoreCase(prefix.get(), prefix.Length())) {
         499               0 :             newHost.Assign(oldHost);
         500               0 :             newHost.Append(suffix);
         501                 :         }
         502               0 :         else if (!suffix.IsEmpty()) {
         503               0 :             newHost.Assign(prefix);
         504               0 :             newHost.Append(oldHost);
         505                 :         }
         506                 :         else
         507                 :         {
         508                 :             // Do nothing
         509               0 :             return false;
         510                 :         }
         511                 :     }
         512                 :     else
         513                 :     {
         514                 :         // Do nothing
         515               2 :         return false;
         516                 :     }
         517                 :
         518               0 :     if (newHost.IsEmpty()) {
         519               0 :         return false;
         520                 :     }
         521                 :
         522                 :     // Assign the new host string over the old one
         523               0 :     aURI->SetHost(newHost);
         524               0 :     return true;
         525                 : }
         526                 :
         527                 : /**
         528                 :  * Check if the host name starts with ftp\d*\. and it's not directly followed
         529                 :  * by the tld.
         530                 :  */
         531               0 : bool nsDefaultURIFixup::IsLikelyFTP(const nsCString &aHostSpec)
         532                 : {
         533               0 :     bool likelyFTP = false;
         534               0 :     if (aHostSpec.EqualsIgnoreCase("ftp", 3)) {
         535               0 :         nsACString::const_iterator iter;
         536               0 :         nsACString::const_iterator end;
         537               0 :         aHostSpec.BeginReading(iter);
         538               0 :         aHostSpec.EndReading(end);
         539               0 :         iter.advance(3); // move past the "ftp" part
         540                 :
         541               0 :         while (iter != end)
         542                 :         {
         543               0 :             if (*iter == '.') {
         544                 :                 // now make sure the name has at least one more dot in it
         545               0 :                 ++iter;
         546               0 :                 while (iter != end)
         547                 :                 {
         548               0 :                     if (*iter == '.') {
         549               0 :                         likelyFTP = true;
         550               0 :                         break;
         551                 :                     }
         552               0 :                     ++iter;
         553                 :                 }
         554               0 :                 break;
         555                 :             }
         556               0 :             else if (!nsCRT::IsAsciiDigit(*iter)) {
         557               0 :                 break;
         558                 :             }
         559               0 :             ++iter;
         560                 :         }
         561                 :     }
         562               0 :     return likelyFTP;
         563                 : }
         564                 :
         565               4 : nsresult nsDefaultURIFixup::FileURIFixup(const nsACString& aStringURI,
         566                 :                                          nsIURI** aURI)
         567                 : {
         568               8 :     nsCAutoString uriSpecOut;
         569                 :
         570               4 :     nsresult rv = ConvertFileToStringURI(aStringURI, uriSpecOut);
         571               4 :     if (NS_SUCCEEDED(rv))
         572                 :     {
         573                 :         // if this is file url, uriSpecOut is already in FS charset
         574               0 :         if(NS_SUCCEEDED(NS_NewURI(aURI, uriSpecOut.get(), nsnull)))
         575               0 :             return NS_OK;
         576                 :     }
         577               4 :     return NS_ERROR_FAILURE;
         578                 : }
         579                 :
         580               4 : nsresult nsDefaultURIFixup::ConvertFileToStringURI(const nsACString& aIn,
         581                 :                                                    nsCString& aOut)
         582                 : {
         583               4 :     bool attemptFixup = false;
         584                 :
         585                 : #if defined(XP_WIN) || defined(XP_OS2)
         586                 :     // Check for \ in the url-string or just a drive (PC)
         587                 :     if(kNotFound != aIn.FindChar('\\') ||
         588                 :        (aIn.Length() == 2 && (aIn.Last() == ':' || aIn.Last() == '|')))
         589                 :     {
         590                 :         attemptFixup = true;
         591                 :     }
         592                 : #elif defined(XP_UNIX)
         593                 :     // Check if it starts with / (UNIX)
         594               4 :     if(aIn.First() == '/')
         595                 :     {
         596               0 :         attemptFixup = true;
         597                 :     }
         598                 : #else
         599                 :     // Do nothing (All others for now)
         600                 : #endif
         601                 :
         602               4 :     if (attemptFixup)
         603                 :     {
         604                 :         // Test if this is a valid path by trying to create a local file
         605                 :         // object. The URL of that is returned if successful.
         606                 :
         607                 :         // NOTE: Please be sure to check that the call to NS_NewLocalFile
         608                 :         //       rejects bad file paths when using this code on a new
         609                 :         //       platform.
         610                 :
         611               0 :         nsCOMPtr<nsILocalFile> filePath;
         612                 :         nsresult rv;
         613                 :
         614                 :         // this is not the real fix but a temporary fix
         615                 :         // in order to really fix the problem, we need to change the
         616                 :         // nsICmdLineService interface to use wstring to pass paramenters
         617                 :         // instead of string since path name and other argument could be
         618                 :         // in non ascii.(see bug 87127) Since it is too risky to make interface change right
         619                 :         // now, we decide not to do so now.
         620                 :         // Therefore, the aIn we receive here maybe already in damage form
         621                 :         // (e.g. treat every bytes as ISO-8859-1 and cast up to PRUnichar
         622                 :         //  while the real data could be in file system charset )
         623                 :         // we choice the following logic which will work for most of the case.
         624                 :         // Case will still failed only if it meet ALL the following condiction:
         625                 :         //    1. running on CJK, Russian, or Greek system, and
         626                 :         //    2. user type it from URL bar
         627                 :         //    3. the file name contains character in the range of
         628                 :         //       U+00A1-U+00FF but encode as different code point in file
         629                 :         //       system charset (e.g. ACP on window)- this is very rare case
         630                 :         // We should remove this logic and convert to File system charset here
         631                 :         // once we change nsICmdLineService to use wstring and ensure
         632                 :         // all the Unicode data come in is correctly converted.
         633                 :         // XXXbz nsICmdLineService doesn't hand back unicode, so in some cases
         634                 :         // what we have is actually a "utf8" version of a "utf16" string that's
         635                 :         // actually byte-expanded native-encoding data.  Someone upstream needs
         636                 :         // to stop using AssignWithConversion and do things correctly.  See bug
         637                 :         // 58866 for what happens if we remove this
         638                 :         // PossiblyByteExpandedFileName check.
         639               0 :         NS_ConvertUTF8toUTF16 in(aIn);
         640               0 :         if (PossiblyByteExpandedFileName(in)) {
         641                 :           // removes high byte
         642               0 :           rv = NS_NewNativeLocalFile(NS_LossyConvertUTF16toASCII(in), false, getter_AddRefs(filePath));
         643                 :         }
         644                 :         else {
         645                 :           // input is unicode
         646               0 :           rv = NS_NewLocalFile(in, false, getter_AddRefs(filePath));
         647                 :         }
         648                 :
         649               0 :         if (NS_SUCCEEDED(rv))
         650                 :         {
         651               0 :             NS_GetURLSpecFromFile(filePath, aOut);
         652               0 :             return NS_OK;
         653                 :         }
         654                 :     }
         655                 :
         656               4 :     return NS_ERROR_FAILURE;
         657                 : }
         658                 :
         659               0 : bool nsDefaultURIFixup::PossiblyHostPortUrl(const nsACString &aUrl)
         660                 : {
         661                 :     // Oh dear, the protocol is invalid. Test if the protocol might
         662                 :     // actually be a url without a protocol:
         663                 :     //
         664                 :     //   http://www.faqs.org/rfcs/rfc1738.html
         665                 :     //   http://www.faqs.org/rfcs/rfc2396.html
         666                 :     //
         667                 :     // e.g. Anything of the form:
         668                 :     //
         669                 :     //   <hostname>:<port> or
         670                 :     //   <hostname>:<port>/
         671                 :     //
         672                 :     // Where <hostname> is a string of alphanumeric characters and dashes
         673                 :     // separated by dots.
         674                 :     // and <port> is a 5 or less digits. This actually breaks the rfc2396
         675                 :     // definition of a scheme which allows dots in schemes.
         676                 :     //
         677                 :     // Note:
         678                 :     //   People expecting this to work with
         679                 :     //   <user>:<password>@<host>:<port>/<url-path> will be disappointed!
         680                 :     //
         681                 :     // Note: Parser could be a lot tighter, tossing out silly hostnames
         682                 :     //       such as those containing consecutive dots and so on.
         683                 :
         684                 :     // Read the hostname which should of the form
         685                 :     // [a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]+)*:
         686                 :
         687               0 :     nsACString::const_iterator iterBegin;
         688               0 :     nsACString::const_iterator iterEnd;
         689               0 :     aUrl.BeginReading(iterBegin);
         690               0 :     aUrl.EndReading(iterEnd);
         691               0 :     nsACString::const_iterator iter = iterBegin;
         692                 :
         693               0 :     while (iter != iterEnd)
         694                 :     {
         695               0 :         PRUint32 chunkSize = 0;
         696                 :         // Parse a chunk of the address
         697               0 :         while (iter != iterEnd &&
         698               0 :                (*iter == '-' ||
         699               0 :                 nsCRT::IsAsciiAlpha(*iter) ||
         700               0 :                 nsCRT::IsAsciiDigit(*iter)))
         701                 :         {
         702               0 :             ++chunkSize;
         703               0 :             ++iter;
         704                 :         }
         705               0 :         if (chunkSize == 0 || iter == iterEnd)
         706                 :         {
         707               0 :             return false;
         708                 :         }
         709               0 :         if (*iter == ':')
         710                 :         {
         711                 :             // Go onto checking the for the digits
         712               0 :             break;
         713                 :         }
         714               0 :         if (*iter != '.')
         715                 :         {
         716                 :             // Whatever it is, it ain't a hostname!
         717               0 :             return false;
         718                 :         }
         719               0 :         ++iter;
         720                 :     }
         721               0 :     if (iter == iterEnd)
         722                 :     {
         723                 :         // No point continuing since there is no colon
         724               0 :         return false;
         725                 :     }
         726               0 :     ++iter;
         727                 :
         728                 :     // Count the number of digits after the colon and before the
         729                 :     // next forward slash (or end of string)
         730                 :
         731               0 :     PRUint32 digitCount = 0;
         732               0 :     while (iter != iterEnd && digitCount <= 5)
         733                 :     {
         734               0 :         if (nsCRT::IsAsciiDigit(*iter))
         735                 :         {
         736               0 :             digitCount++;
         737                 :         }
         738               0 :         else if (*iter == '/')
         739                 :         {
         740               0 :             break;
         741                 :         }
         742                 :         else
         743                 :         {
         744                 :             // Whatever it is, it ain't a port!
         745               0 :             return false;
         746                 :         }
         747               0 :         ++iter;
         748                 :     }
         749               0 :     if (digitCount == 0 || digitCount > 5)
         750                 :     {
         751                 :         // No digits or more digits than a port would have.
         752               0 :         return false;
         753                 :     }
         754                 :
         755                 :     // Yes, it's possibly a host:port url
         756               0 :     return true;
         757                 : }
         758                 :
         759               0 : bool nsDefaultURIFixup::PossiblyByteExpandedFileName(const nsAString& aIn)
         760                 : {
         761                 :     // XXXXX HACK XXXXX : please don't copy this code.
         762                 :     // There are cases where aIn contains the locale byte chars padded to short
         763                 :     // (thus the name "ByteExpanded"); whereas other cases
         764                 :     // have proper Unicode code points.
         765                 :     // This is a temporary fix.  Please refer to 58866, 86948
         766                 :
         767               0 :     nsReadingIterator<PRUnichar> iter;
         768               0 :     nsReadingIterator<PRUnichar> iterEnd;
         769               0 :     aIn.BeginReading(iter);
         770               0 :     aIn.EndReading(iterEnd);
         771               0 :     while (iter != iterEnd)
         772                 :     {
         773               0 :         if (*iter >= 0x0080 && *iter <= 0x00FF)
         774               0 :             return true;
         775               0 :         ++iter;
         776                 :     }
         777               0 :     return false;
         778                 : }
         779                 :
         780               0 : const char * nsDefaultURIFixup::GetFileSystemCharset()
         781                 : {
         782               0 :   if (mFsCharset.IsEmpty())
         783                 :   {
         784                 :     nsresult rv;
         785               0 :     nsCAutoString charset;
         786               0 :     nsCOMPtr<nsIPlatformCharset> plat(do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv));
         787               0 :     if (NS_SUCCEEDED(rv))
         788               0 :       rv = plat->GetCharset(kPlatformCharsetSel_FileName, charset);
         789                 :
         790               0 :     if (charset.IsEmpty())
         791               0 :       mFsCharset.AssignLiteral("ISO-8859-1");
         792                 :     else
         793               0 :       mFsCharset.Assign(charset);
         794                 :   }
         795                 :
         796               0 :   return mFsCharset.get();
         797                 : }
         798                 :
         799               0 : const char * nsDefaultURIFixup::GetCharsetForUrlBar()
         800                 : {
         801               0 :   const char *charset = GetFileSystemCharset();
         802               0 :   return charset;
         803                 : }
         804                 :
         805               0 : nsresult nsDefaultURIFixup::KeywordURIFixup(const nsACString & aURIString,
         806                 :                                             nsIURI** aURI)
         807                 : {
         808                 :     // These are keyword formatted strings
         809                 :     // "what is mozilla"
         810                 :     // "what is mozilla?"
         811                 :     // "docshell site:mozilla.org" - has no dot/colon in the first space-separated substring
         812                 :     // "?mozilla" - anything that begins with a question mark
         813                 :     // "?site:mozilla.org docshell"
         814                 :     // Things that have a quote before the first dot/colon
         815                 :
         816                 :     // These are not keyword formatted strings
         817                 :     // "www.blah.com" - first space-separated substring contains a dot, doesn't start with "?"
         818                 :     // "www.blah.com stuff"
         819                 :     // "nonQualifiedHost:80" - first space-separated substring contains a colon, doesn't start with "?"
         820                 :     // "nonQualifiedHost:80 args"
         821                 :     // "nonQualifiedHost?"
         822                 :     // "nonQualifiedHost?args"
         823                 :     // "nonQualifiedHost?some args"
         824                 :
         825                 :     // Note: PRUint32(kNotFound) is greater than any actual location
         826                 :     // in practice.  So if we cast all locations to PRUint32, then a <
         827                 :     // b guarantees that either b is kNotFound and a is found, or both
         828                 :     // are found and a found before b.
         829               0 :     PRUint32 dotLoc   = PRUint32(aURIString.FindChar('.'));
         830               0 :     PRUint32 colonLoc = PRUint32(aURIString.FindChar(':'));
         831               0 :     PRUint32 spaceLoc = PRUint32(aURIString.FindChar(' '));
         832               0 :     if (spaceLoc == 0) {
         833                 :         // Treat this as not found
         834               0 :         spaceLoc = PRUint32(kNotFound);
         835                 :     }
         836               0 :     PRUint32 qMarkLoc = PRUint32(aURIString.FindChar('?'));
         837               0 :     PRUint32 quoteLoc = NS_MIN(PRUint32(aURIString.FindChar('"')),
         838               0 :                                PRUint32(aURIString.FindChar('\'')));
         839                 :
         840               0 :     if (((spaceLoc < dotLoc || quoteLoc < dotLoc) &&
         841                 :          (spaceLoc < colonLoc || quoteLoc < colonLoc) &&
         842                 :          (spaceLoc < qMarkLoc || quoteLoc < qMarkLoc)) ||
         843                 :         qMarkLoc == 0)
         844                 :     {
         845               0 :         KeywordToURI(aURIString, aURI);
         846                 :     }
         847                 :
         848               0 :     if(*aURI)
         849               0 :         return NS_OK;
         850                 :
         851               0 :     return NS_ERROR_FAILURE;
         852                 : }
         853                 :
         854                 :
         855               0 : nsresult NS_NewURIFixup(nsIURIFixup **aURIFixup)
         856                 : {
         857               0 :     nsDefaultURIFixup *fixup = new nsDefaultURIFixup;
         858               0 :     if (fixup == nsnull)
         859                 :     {
         860               0 :         return NS_ERROR_OUT_OF_MEMORY;
         861                 :     }
         862               0 :     return fixup->QueryInterface(NS_GET_IID(nsIURIFixup), (void **) aURIFixup);
         863                 : }
         864                 :

Generated by: LCOV version 1.7