LCOV - code coverage report
Current view: top level - netwerk/base - nsStandardURL.h (source / functions) Hit Total Coverage
Test: output.info Lines: 42 68 61.8 %
Date: 2017-07-14 16:53:18 Functions: 20 26 76.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /* This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       5             : 
       6             : #ifndef nsStandardURL_h__
       7             : #define nsStandardURL_h__
       8             : 
       9             : #include "nsString.h"
      10             : #include "nsISerializable.h"
      11             : #include "nsIFileURL.h"
      12             : #include "nsIStandardURL.h"
      13             : #include "mozilla/Encoding.h"
      14             : #include "nsIObserver.h"
      15             : #include "nsCOMPtr.h"
      16             : #include "nsURLHelper.h"
      17             : #include "nsIClassInfo.h"
      18             : #include "nsISizeOf.h"
      19             : #include "mozilla/Attributes.h"
      20             : #include "mozilla/LinkedList.h"
      21             : #include "mozilla/MemoryReporting.h"
      22             : #include "nsIIPCSerializableURI.h"
      23             : #include "nsISensitiveInfoHiddenURI.h"
      24             : #include "RustURL.h"
      25             : 
      26             : #ifdef NS_BUILD_REFCNT_LOGGING
      27             : #define DEBUG_DUMP_URLS_AT_SHUTDOWN
      28             : #endif
      29             : 
      30             : class nsIBinaryInputStream;
      31             : class nsIBinaryOutputStream;
      32             : class nsIIDNService;
      33             : class nsIPrefBranch;
      34             : class nsIFile;
      35             : class nsIURLParser;
      36             : 
      37             : namespace mozilla {
      38             : namespace net {
      39             : 
      40             : //-----------------------------------------------------------------------------
      41             : // standard URL implementation
      42             : //-----------------------------------------------------------------------------
      43             : 
      44             : class nsStandardURL : public nsIFileURL
      45             :                     , public nsIStandardURL
      46             :                     , public nsISerializable
      47             :                     , public nsIClassInfo
      48             :                     , public nsISizeOf
      49             :                     , public nsIIPCSerializableURI
      50             :                     , public nsISensitiveInfoHiddenURI
      51             : #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
      52             :                     , public LinkedListElement<nsStandardURL>
      53             : #endif
      54             : {
      55             : protected:
      56             :     virtual ~nsStandardURL();
      57             : 
      58             : public:
      59             :     NS_DECL_ISUPPORTS
      60             :     NS_DECL_NSIURI
      61             :     NS_DECL_NSIURL
      62             :     NS_DECL_NSIFILEURL
      63             :     NS_DECL_NSISTANDARDURL
      64             :     NS_DECL_NSISERIALIZABLE
      65             :     NS_DECL_NSICLASSINFO
      66             :     NS_DECL_NSIMUTABLE
      67             :     NS_DECL_NSIIPCSERIALIZABLEURI
      68             :     NS_DECL_NSISENSITIVEINFOHIDDENURI
      69             : 
      70             :     // nsISizeOf
      71             :     virtual size_t SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const override;
      72             :     virtual size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override;
      73             : 
      74             :     explicit nsStandardURL(bool aSupportsFileURL = false, bool aTrackURL = true);
      75             : 
      76             :     static void InitGlobalObjects();
      77             :     static void ShutdownGlobalObjects();
      78             : 
      79             : public: /* internal -- HPUX compiler can't handle this being private */
      80             :     //
      81             :     // location and length of an url segment relative to mSpec
      82             :     //
      83             :     struct URLSegment
      84             :     {
      85             :         uint32_t mPos;
      86             :         int32_t  mLen;
      87             : 
      88      128430 :         URLSegment() : mPos(0), mLen(-1) {}
      89         447 :         URLSegment(uint32_t pos, int32_t len) : mPos(pos), mLen(len) {}
      90       47190 :         URLSegment(const URLSegment& aCopy) : mPos(aCopy.mPos), mLen(aCopy.mLen) {}
      91       56628 :         void Reset() { mPos = 0; mLen = -1; }
      92             :         // Merge another segment following this one to it if they're contiguous
      93             :         // Assumes we have something like "foo;bar" where this object is 'foo' and right
      94             :         // is 'bar'.
      95           0 :         void Merge(const nsCString &spec, const char separator, const URLSegment &right) {
      96           0 :             if (mLen >= 0 &&
      97           0 :                 *(spec.get() + mPos + mLen) == separator &&
      98           0 :                 mPos + mLen + 1 == right.mPos) {
      99           0 :                 mLen += 1 + right.mLen;
     100             :             }
     101           0 :         }
     102             :     };
     103             : 
     104             :     //
     105             :     // Pref observer
     106             :     //
     107             :     class nsPrefObserver final : public nsIObserver
     108             :     {
     109           0 :         ~nsPrefObserver() {}
     110             : 
     111             :     public:
     112             :         NS_DECL_ISUPPORTS
     113             :         NS_DECL_NSIOBSERVER
     114             : 
     115           3 :         nsPrefObserver() { }
     116             :     };
     117             :     friend class nsPrefObserver;
     118             : 
     119             :     //
     120             :     // URL segment encoder : performs charset conversion and URL escaping.
     121             :     //
     122             :     class nsSegmentEncoder
     123             :     {
     124             :     public:
     125             :         explicit nsSegmentEncoder(const char *charset);
     126             : 
     127             :         // Encode the given segment if necessary, and return the length of
     128             :         // the encoded segment.  The encoded segment is appended to |buf|
     129             :         // if and only if encoding is required.
     130             :         int32_t EncodeSegmentCount(const char *str,
     131             :                                    const URLSegment &segment,
     132             :                                    int16_t mask,
     133             :                                    nsCString& buf,
     134             :                                    bool& appended,
     135             :                                    uint32_t extraLen = 0);
     136             : 
     137             :         // Encode the given string if necessary, and return a reference to
     138             :         // the encoded string.  Returns a reference to |buf| if encoding
     139             :         // is required.  Otherwise, a reference to |str| is returned.
     140             :         const nsACString& EncodeSegment(const nsACString& str,
     141             :                                         int16_t mask,
     142             :                                         nsCString& buf);
     143             :     private:
     144             :       const Encoding* mEncoding;
     145             :     };
     146             :     friend class nsSegmentEncoder;
     147             : 
     148             :     static nsresult NormalizeIPv4(const nsACString& host, nsCString& result);
     149             : 
     150             : protected:
     151             :     // enum used in a few places to specify how .ref attribute should be handled
     152             :     enum RefHandlingEnum {
     153             :         eIgnoreRef,
     154             :         eHonorRef,
     155             :         eReplaceRef
     156             :     };
     157             : 
     158             :     // Helper to share code between Equals and EqualsExceptRef
     159             :     // NOTE: *not* virtual, because no one needs to override this so far...
     160             :     nsresult EqualsInternal(nsIURI* unknownOther,
     161             :                             RefHandlingEnum refHandlingMode,
     162             :                             bool* result);
     163             : 
     164             :     virtual nsStandardURL* StartClone();
     165             : 
     166             :     // Helper to share code between Clone methods.
     167             :     nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
     168             :                            const nsACString& newRef,
     169             :                            nsIURI** aClone);
     170             :     // Helper method that copies member variables from the source StandardURL
     171             :     // if copyCached = true, it will also copy mFile and mDisplayHost
     172             :     nsresult CopyMembers(nsStandardURL * source, RefHandlingEnum mode,
     173             :                          const nsACString& newRef,
     174             :                          bool copyCached = false);
     175             : 
     176             :     // Helper for subclass implementation of GetFile().  Subclasses that map
     177             :     // URIs to files in a special way should implement this method.  It should
     178             :     // ensure that our mFile is initialized, if it's possible.
     179             :     // returns NS_ERROR_NO_INTERFACE if the url does not map to a file
     180             :     virtual nsresult EnsureFile();
     181             : 
     182             : private:
     183        3614 :     int32_t  Port() { return mPort == -1 ? mDefaultPort : mPort; }
     184             : 
     185             :     void     ReplacePortInSpec(int32_t aNewPort);
     186             :     void     Clear();
     187             :     void     InvalidateCache(bool invalidateCachedFile = true);
     188             : 
     189             :     bool     ValidIPv6orHostname(const char *host, uint32_t aLen);
     190             :     static bool     IsValidOfBase(unsigned char c, const uint32_t base);
     191             :     nsresult NormalizeIDN(const nsACString& host, nsCString& result);
     192             :     void     CoalescePath(netCoalesceFlags coalesceFlag, char *path);
     193             : 
     194             :     uint32_t AppendSegmentToBuf(char *, uint32_t, const char *,
     195             :                                 const URLSegment &input, URLSegment &output,
     196             :                                 const nsCString *esc=nullptr,
     197             :                                 bool useEsc = false, int32_t* diff = nullptr);
     198             :     uint32_t AppendToBuf(char *, uint32_t, const char *, uint32_t);
     199             : 
     200             :     nsresult BuildNormalizedSpec(const char *spec);
     201             : 
     202             :     bool     SegmentIs(const URLSegment &s1, const char *val, bool ignoreCase = false);
     203             :     bool     SegmentIs(const char* spec, const URLSegment &s1, const char *val, bool ignoreCase = false);
     204             :     bool     SegmentIs(const URLSegment &s1, const char *val, const URLSegment &s2, bool ignoreCase = false);
     205             : 
     206             :     int32_t  ReplaceSegment(uint32_t pos, uint32_t len, const char *val, uint32_t valLen);
     207             :     int32_t  ReplaceSegment(uint32_t pos, uint32_t len, const nsACString &val);
     208             : 
     209             :     nsresult ParseURL(const char *spec, int32_t specLen);
     210             :     nsresult ParsePath(const char *spec, uint32_t pathPos, int32_t pathLen = -1);
     211             : 
     212             :     char    *AppendToSubstring(uint32_t pos, int32_t len, const char *tail);
     213             : 
     214             :     // dependent substring helpers
     215             :     const nsDependentCSubstring Segment(uint32_t pos, int32_t len); // see below
     216       13874 :     const nsDependentCSubstring Segment(const URLSegment &s) { return Segment(s.mPos, s.mLen); }
     217             : 
     218             :     // dependent substring getters
     219             :     const nsDependentCSubstring Prepath();  // see below
     220        5380 :     const nsDependentCSubstring Scheme()    { return Segment(mScheme); }
     221             :     const nsDependentCSubstring Userpass(bool includeDelim = false); // see below
     222           6 :     const nsDependentCSubstring Username()  { return Segment(mUsername); }
     223           3 :     const nsDependentCSubstring Password()  { return Segment(mPassword); }
     224             :     const nsDependentCSubstring Hostport(); // see below
     225             :     const nsDependentCSubstring Host();     // see below
     226        2605 :     const nsDependentCSubstring Path()      { return Segment(mPath); }
     227        1614 :     const nsDependentCSubstring Filepath()  { return Segment(mFilepath); }
     228           6 :     const nsDependentCSubstring Directory() { return Segment(mDirectory); }
     229             :     const nsDependentCSubstring Filename(); // see below
     230           0 :     const nsDependentCSubstring Basename()  { return Segment(mBasename); }
     231           0 :     const nsDependentCSubstring Extension() { return Segment(mExtension); }
     232        2192 :     const nsDependentCSubstring Query()     { return Segment(mQuery); }
     233        1616 :     const nsDependentCSubstring Ref()       { return Segment(mRef); }
     234             : 
     235             :     // shift the URLSegments to the right by diff
     236             :     void ShiftFromAuthority(int32_t diff);
     237             :     void ShiftFromUsername(int32_t diff);
     238             :     void ShiftFromPassword(int32_t diff);
     239             :     void ShiftFromHost(int32_t diff);
     240             :     void ShiftFromPath(int32_t diff);
     241             :     void ShiftFromFilepath(int32_t diff);
     242             :     void ShiftFromDirectory(int32_t diff);
     243             :     void ShiftFromBasename(int32_t diff);
     244             :     void ShiftFromExtension(int32_t diff);
     245             :     void ShiftFromQuery(int32_t diff);
     246             :     void ShiftFromRef(int32_t diff);
     247             : 
     248             :     // fastload helper functions
     249             :     nsresult ReadSegment(nsIBinaryInputStream *, URLSegment &);
     250             :     nsresult WriteSegment(nsIBinaryOutputStream *, const URLSegment &);
     251             : 
     252             :     static void PrefsChanged(nsIPrefBranch *prefs, const char *pref);
     253             : 
     254             :     void FindHostLimit(nsACString::const_iterator& aStart,
     255             :                        nsACString::const_iterator& aEnd);
     256             : 
     257             :     // mSpec contains the normalized version of the URL spec (UTF-8 encoded).
     258             :     nsCString mSpec;
     259             :     int32_t   mDefaultPort;
     260             :     int32_t   mPort;
     261             : 
     262             :     // url parts (relative to mSpec)
     263             :     URLSegment mScheme;
     264             :     URLSegment mAuthority;
     265             :     URLSegment mUsername;
     266             :     URLSegment mPassword;
     267             :     URLSegment mHost;
     268             :     URLSegment mPath;
     269             :     URLSegment mFilepath;
     270             :     URLSegment mDirectory;
     271             :     URLSegment mBasename;
     272             :     URLSegment mExtension;
     273             :     URLSegment mQuery;
     274             :     URLSegment mRef;
     275             : 
     276             :     nsCString              mOriginCharset;
     277             :     nsCOMPtr<nsIURLParser> mParser;
     278             : 
     279             :     // mFile is protected so subclasses can access it directly
     280             : protected:
     281             :     nsCOMPtr<nsIFile>      mFile;  // cached result for nsIFileURL::GetFile
     282             : 
     283             : private:
     284             :     // cached result for nsIURI::GetDisplayHost
     285             :     nsCString              mDisplayHost;
     286             : 
     287             :     enum {
     288             :         eEncoding_Unknown,
     289             :         eEncoding_ASCII,
     290             :         eEncoding_UTF8
     291             :     };
     292             : 
     293             :     uint32_t mSpecEncoding    : 2; // eEncoding_xxx
     294             :     uint32_t mURLType         : 2; // nsIStandardURL::URLTYPE_xxx
     295             :     uint32_t mMutable         : 1; // nsIStandardURL::mutable
     296             :     uint32_t mSupportsFileURL : 1; // QI to nsIFileURL?
     297             :     uint32_t mCheckedIfHostA  : 1; // If set to true, it means either that
     298             :                                    // mDisplayHost has a been initialized, or
     299             :                                    // that the hostname is not punycode
     300             : 
     301             :     // global objects.  don't use COMPtr as its destructor will cause a
     302             :     // coredump if we leak it.
     303             :     static nsIIDNService               *gIDN;
     304             :     static const char                   gHostLimitDigits[];
     305             :     static bool                         gInitialized;
     306             :     static bool                         gPunycodeHost;
     307             : 
     308             : public:
     309             : #ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
     310           0 :     void PrintSpec() const { printf("  %s\n", mSpec.get()); }
     311             : #endif
     312             : 
     313             : #ifdef MOZ_RUST_URLPARSE
     314             :     static Atomic<bool>                gRustEnabled;
     315             :     RefPtr<RustURL>                    mRustURL;
     316             : #endif
     317             : };
     318             : 
     319             : #define NS_THIS_STANDARDURL_IMPL_CID                 \
     320             : { /* b8e3e97b-1ccd-4b45-af5a-79596770f5d7 */         \
     321             :     0xb8e3e97b,                                      \
     322             :     0x1ccd,                                          \
     323             :     0x4b45,                                          \
     324             :     {0xaf, 0x5a, 0x79, 0x59, 0x67, 0x70, 0xf5, 0xd7} \
     325             : }
     326             : 
     327             : //-----------------------------------------------------------------------------
     328             : // Dependent substring getters
     329             : //-----------------------------------------------------------------------------
     330             : 
     331             : inline const nsDependentCSubstring
     332       13874 : nsStandardURL::Segment(uint32_t pos, int32_t len)
     333             : {
     334       13874 :     if (len < 0) {
     335        2952 :         pos = 0;
     336        2952 :         len = 0;
     337             :     }
     338       13874 :     return Substring(mSpec, pos, uint32_t(len));
     339             : }
     340             : 
     341             : inline const nsDependentCSubstring
     342           4 : nsStandardURL::Prepath()
     343             : {
     344           4 :     uint32_t len = 0;
     345           4 :     if (mAuthority.mLen >= 0)
     346           4 :         len = mAuthority.mPos + mAuthority.mLen;
     347           4 :     return Substring(mSpec, 0, len);
     348             : }
     349             : 
     350             : inline const nsDependentCSubstring
     351          24 : nsStandardURL::Userpass(bool includeDelim)
     352             : {
     353          24 :     uint32_t pos=0, len=0;
     354             :     // if there is no username, then there can be no password
     355          24 :     if (mUsername.mLen > 0) {
     356           0 :         pos = mUsername.mPos;
     357           0 :         len = mUsername.mLen;
     358           0 :         if (mPassword.mLen >= 0)
     359           0 :             len += (mPassword.mLen + 1);
     360           0 :         if (includeDelim)
     361           0 :             len++;
     362             :     }
     363          24 :     return Substring(mSpec, pos, len);
     364             : }
     365             : 
     366             : inline const nsDependentCSubstring
     367        1310 : nsStandardURL::Hostport()
     368             : {
     369        1310 :     uint32_t pos=0, len=0;
     370        1310 :     if (mAuthority.mLen > 0) {
     371        1310 :         pos = mHost.mPos;
     372        1310 :         len = mAuthority.mPos + mAuthority.mLen - pos;
     373             :     }
     374        1310 :     return Substring(mSpec, pos, len);
     375             : }
     376             : 
     377             : inline const nsDependentCSubstring
     378        3227 : nsStandardURL::Host()
     379             : {
     380        3227 :     uint32_t pos=0, len=0;
     381        3227 :     if (mHost.mLen > 0) {
     382        3043 :         pos = mHost.mPos;
     383        3043 :         len = mHost.mLen;
     384        3043 :         if (mSpec.CharAt(pos) == '[' && mSpec.CharAt(pos + len - 1) == ']') {
     385           0 :             pos++;
     386           0 :             len -= 2;
     387             :         }
     388             :     }
     389        3227 :     return Substring(mSpec, pos, len);
     390             : }
     391             : 
     392             : inline const nsDependentCSubstring
     393           0 : nsStandardURL::Filename()
     394             : {
     395           0 :     uint32_t pos=0, len=0;
     396             :     // if there is no basename, then there can be no extension
     397           0 :     if (mBasename.mLen > 0) {
     398           0 :         pos = mBasename.mPos;
     399           0 :         len = mBasename.mLen;
     400           0 :         if (mExtension.mLen >= 0)
     401           0 :             len += (mExtension.mLen + 1);
     402             :     }
     403           0 :     return Substring(mSpec, pos, len);
     404             : }
     405             : 
     406             : } // namespace net
     407             : } // namespace mozilla
     408             : 
     409             : #endif // nsStandardURL_h__

Generated by: LCOV version 1.13