1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 nsIDNService_h__ 7 #define nsIDNService_h__ 8 9 #include "nsIIDNService.h" 10 #include "nsCOMPtr.h" 11 #include "nsIObserver.h" 12 #include "nsUnicodeScriptCodes.h" 13 #include "nsWeakReference.h" 14 15 #ifdef IDNA2008 16 #include "unicode/uidna.h" 17 #else 18 #include "nsIUnicodeNormalizer.h" 19 #include "nsIDNKitInterface.h" 20 #endif 21 22 #include "nsString.h" 23 24 class nsIPrefBranch; 25 26 //----------------------------------------------------------------------------- 27 // nsIDNService 28 //----------------------------------------------------------------------------- 29 30 class nsIDNService final : public nsIIDNService, 31 public nsIObserver, 32 public nsSupportsWeakReference 33 { 34 public: 35 NS_DECL_THREADSAFE_ISUPPORTS 36 NS_DECL_NSIIDNSERVICE 37 NS_DECL_NSIOBSERVER 38 39 nsIDNService(); 40 41 nsresult Init(); 42 43 protected: 44 virtual ~nsIDNService(); 45 46 private: 47 enum stringPrepFlag { 48 eStringPrepForDNS, 49 eStringPrepForUI, 50 eStringPrepIgnoreErrors 51 }; 52 53 /** 54 * Convert the following characters that must be recognized as label 55 * separators per RFC 3490 to ASCII full stop characters 56 * 57 * U+3002 (ideographic full stop) 58 * U+FF0E (fullwidth full stop) 59 * U+FF61 (halfwidth ideographic full stop) 60 */ 61 void normalizeFullStops(nsAString& s); 62 63 /** 64 * Convert and encode a DNS label in ACE/punycode. 65 * @param flag 66 * if eStringPrepIgnoreErrors, all non-ASCII labels are 67 * converted to punycode. 68 * if eStringPrepForUI, only labels that are considered safe 69 * for display are converted. 70 * @see isLabelSafe 71 * if eStringPrepForDNS and stringPrep finds an illegal 72 * character, returns NS_FAILURE and out is empty 73 */ 74 nsresult stringPrepAndACE(const nsAString& in, nsACString& out, 75 stringPrepFlag flag); 76 77 /** 78 * Convert a DNS label using the stringprep profile defined in RFC 3454 79 */ 80 nsresult stringPrep(const nsAString& in, nsAString& out, stringPrepFlag flag); 81 82 /** 83 * Decode an ACE-encoded DNS label to UTF-8 84 * 85 * @param flag 86 * if eStringPrepForUI and the label is not considered safe to 87 * display, the output is the same as the input 88 * @see isLabelSafe 89 */ 90 nsresult decodeACE(const nsACString& in, nsACString& out, 91 stringPrepFlag flag); 92 93 /** 94 * Convert complete domain names between UTF8 and ACE and vice versa 95 * 96 * @param flag is passed to decodeACE or stringPrepAndACE for each 97 * label individually, so the output may contain some labels in 98 * punycode and some in UTF-8 99 */ 100 nsresult UTF8toACE(const nsACString& input, nsACString& ace, 101 stringPrepFlag flag); 102 nsresult ACEtoUTF8(const nsACString& input, nsACString& _retval, 103 stringPrepFlag flag); 104 105 bool isInWhitelist(const nsACString &host); 106 void prefsChanged(nsIPrefBranch *prefBranch, const char16_t *pref); 107 108 /** 109 * Determine whether a label is considered safe to display to the user 110 * according to the algorithm defined in UTR 39 and the profile 111 * selected in mRestrictionProfile. 112 * 113 * For the ASCII-only profile, returns false for all labels containing 114 * non-ASCII characters. 115 * 116 * For the other profiles, returns false for labels containing any of 117 * the following: 118 * 119 * Characters in scripts other than the "recommended scripts" and 120 * "aspirational scripts" defined in 121 * http://www.unicode.org/reports/tr31/#Table_Recommended_Scripts 122 * and http://www.unicode.org/reports/tr31/#Aspirational_Use_Scripts 123 * This includes codepoints that are not defined as Unicode 124 * characters 125 * 126 * Illegal combinations of scripts (@see illegalScriptCombo) 127 * 128 * Numbers from more than one different numbering system 129 * 130 * Sequences of the same non-spacing mark 131 * 132 * Both simplified-only and traditional-only Chinese characters 133 * XXX this test was disabled by bug 857481 134 */ 135 bool isLabelSafe(const nsAString &label); 136 137 /** 138 * Determine whether a combination of scripts in a single label is 139 * permitted according to the algorithm defined in UTR 39 and the 140 * profile selected in mRestrictionProfile. 141 * 142 * For the "Highly restrictive" profile, all characters in each 143 * identifier must be from a single script, or from the combinations: 144 * Latin + Han + Hiragana + Katakana; 145 * Latin + Han + Bopomofo; or 146 * Latin + Han + Hangul 147 * 148 * For the "Moderately restrictive" profile, Latin is also allowed 149 * with other scripts except Cyrillic and Greek 150 */ 151 bool illegalScriptCombo(mozilla::unicode::Script script, 152 int32_t& savedScript); 153 154 #ifdef IDNA2008 155 /** 156 * Convert a DNS label from ASCII to Unicode using IDNA2008 157 */ 158 nsresult IDNA2008ToUnicode(const nsACString& input, nsAString& output); 159 160 /** 161 * Convert a DNS label to a normalized form conforming to IDNA2008 162 */ 163 nsresult IDNA2008StringPrep(const nsAString& input, nsAString& output, 164 stringPrepFlag flag); 165 166 UIDNA* mIDNA; 167 #else 168 idn_nameprep_t mNamePrepHandle; 169 nsCOMPtr<nsIUnicodeNormalizer> mNormalizer; 170 #endif 171 nsXPIDLString mIDNBlacklist; 172 173 /** 174 * Flag set by the pref network.IDN_show_punycode. When it is true, 175 * IDNs containing non-ASCII characters are always displayed to the 176 * user in punycode 177 */ 178 bool mShowPunycode; 179 180 /** 181 * Restriction-level Detection profiles defined in UTR 39 182 * http://www.unicode.org/reports/tr39/#Restriction_Level_Detection, 183 * and selected by the pref network.IDN.restriction_profile 184 */ 185 enum restrictionProfile { 186 eASCIIOnlyProfile, 187 eHighlyRestrictiveProfile, 188 eModeratelyRestrictiveProfile 189 }; 190 restrictionProfile mRestrictionProfile; 191 nsCOMPtr<nsIPrefBranch> mIDNWhitelistPrefBranch; 192 bool mIDNUseWhitelist; 193 }; 194 195 #endif // nsIDNService_h__ 196