author arthur.iakab <>
Tue, 03 Apr 2018 18:30:58 +0300
changeset 411462 5ec55f7a95f94cf39d57cdf36abecab914ea48eb
parent 382446 b9855e3e3ce3dae8c2b40cc505dd46637d70615b
child 426850 cae48c105b0c6e218e856d3f9044386f43968099
permissions -rw-r--r--
Backed out changeset 3ff8ce674396 (bug 1447460) on request of tomprince a=backout

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at */

#ifndef nsIDNService_h__
#define nsIDNService_h__

#include "nsIIDNService.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
#include "nsUnicodeScriptCodes.h"
#include "nsWeakReference.h"

#include "unicode/uidna.h"

#include "nsString.h"

class nsIPrefBranch;

// nsIDNService

class nsIDNService final : public nsIIDNService,
                           public nsIObserver,
                           public nsSupportsWeakReference


  nsresult Init();

  virtual ~nsIDNService();

  enum stringPrepFlag {

   * Convert the following characters that must be recognized as label
   *  separators per RFC 3490 to ASCII full stop characters
   * U+3002 (ideographic full stop)
   * U+FF0E (fullwidth full stop)
   * U+FF61 (halfwidth ideographic full stop)
  void normalizeFullStops(nsAString& s);

   * Convert and encode a DNS label in ACE/punycode.
   * @param flag
   *        if eStringPrepIgnoreErrors, all non-ASCII labels are
   *           converted to punycode.
   *        if eStringPrepForUI, only labels that are considered safe
   *           for display are converted.
   *           @see isLabelSafe
   *        if eStringPrepForDNS and stringPrep finds an illegal
   *           character, returns NS_FAILURE and out is empty
  nsresult stringPrepAndACE(const nsAString& in, nsACString& out,
                            stringPrepFlag flag);

   * Convert a DNS label using the stringprep profile defined in RFC 3454
  nsresult stringPrep(const nsAString& in, nsAString& out, stringPrepFlag flag);

   * Decode an ACE-encoded DNS label to UTF-8
   * @param flag
   *        if eStringPrepForUI and the label is not considered safe to
   *           display, the output is the same as the input
   *        @see isLabelSafe
  nsresult decodeACE(const nsACString& in, nsACString& out,
                     stringPrepFlag flag);

   * Convert complete domain names between UTF8 and ACE and vice versa
   * @param flag is passed to decodeACE or stringPrepAndACE for each
   *  label individually, so the output may contain some labels in
   *  punycode and some in UTF-8
  nsresult UTF8toACE(const nsACString& input, nsACString& ace,
                     stringPrepFlag flag);
  nsresult ACEtoUTF8(const nsACString& input, nsACString& _retval,
                     stringPrepFlag flag);

  bool isInWhitelist(const nsACString &host);
  void prefsChanged(nsIPrefBranch *prefBranch, const char16_t *pref);

   * Determine whether a label is considered safe to display to the user
   * according to the algorithm defined in UTR 39 and the profile
   * selected in mRestrictionProfile.
   * For the ASCII-only profile, returns false for all labels containing
   * non-ASCII characters.
   * For the other profiles, returns false for labels containing any of
   * the following:
   *  Characters in scripts other than the "recommended scripts" and
   *   "aspirational scripts" defined in
   *   and
   *  This includes codepoints that are not defined as Unicode
   *   characters
   *  Illegal combinations of scripts (@see illegalScriptCombo)
   *  Numbers from more than one different numbering system
   *  Sequences of the same non-spacing mark
   *  Both simplified-only and traditional-only Chinese characters
   *   XXX this test was disabled by bug 857481
  bool isLabelSafe(const nsAString &label);

   * Determine whether a combination of scripts in a single label is
   * permitted according to the algorithm defined in UTR 39 and the
   * profile selected in mRestrictionProfile.
   * For the "Highly restrictive" profile, all characters in each
   * identifier must be from a single script, or from the combinations:
   *  Latin + Han + Hiragana + Katakana;
   *  Latin + Han + Bopomofo; or
   *  Latin + Han + Hangul
   * For the "Moderately restrictive" profile, Latin is also allowed
   *  with other scripts except Cyrillic and Greek
  bool illegalScriptCombo(mozilla::unicode::Script script,
                          int32_t& savedScript);

   * Convert a DNS label from ASCII to Unicode using IDNA2008
  nsresult IDNA2008ToUnicode(const nsACString& input, nsAString& output);

   * Convert a DNS label to a normalized form conforming to IDNA2008
  nsresult IDNA2008StringPrep(const nsAString& input, nsAString& output,
                              stringPrepFlag flag);


  // We use this mutex to guard access to:
  // |mIDNBlacklist|, |mShowPunycode|, |mRestrictionProfile|,
  // |mIDNUseWhitelist|.
  // These members can only be updated on the main thread and
  // read on any thread. Therefore, acquiring the mutex is required
  // only for threads other than the main thread.
  mozilla::Mutex mLock;

  // guarded by mLock
  nsString mIDNBlacklist;

   * Flag set by the pref network.IDN_show_punycode. When it is true,
   * IDNs containing non-ASCII characters are always displayed to the
   * user in punycode
   * guarded by mLock
  bool mShowPunycode;

   * Restriction-level Detection profiles defined in UTR 39
   * and selected by the pref network.IDN.restriction_profile
   enum restrictionProfile {
  // guarded by mLock;
  restrictionProfile mRestrictionProfile;
  // guarded by mLock;
  nsCOMPtr<nsIPrefBranch> mIDNWhitelistPrefBranch;
  // guarded by mLock
  bool mIDNUseWhitelist;

#endif  // nsIDNService_h__