bitcoinaddressvalidator.cpp raw

   1  // Copyright (c) 2011-present The Bitcoin Core developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <qt/bitcoinaddressvalidator.h>
   6  
   7  #include <key_io.h>
   8  
   9  /* Base58 characters are:
  10       "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
  11  
  12    This is:
  13    - All numbers except for '0'
  14    - All upper-case letters except for 'I' and 'O'
  15    - All lower-case letters except for 'l'
  16  */
  17  
  18  BitcoinAddressEntryValidator::BitcoinAddressEntryValidator(QObject *parent) :
  19      QValidator(parent)
  20  {
  21  }
  22  
  23  QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &pos) const
  24  {
  25      Q_UNUSED(pos);
  26  
  27      // Empty address is "intermediate" input
  28      if (input.isEmpty())
  29          return QValidator::Intermediate;
  30  
  31      // Correction
  32      for (int idx = 0; idx < input.size();)
  33      {
  34          bool removeChar = false;
  35          QChar ch = input.at(idx);
  36          // Corrections made are very conservative on purpose, to avoid
  37          // users unexpectedly getting away with typos that would normally
  38          // be detected, and thus sending to the wrong address.
  39          switch(ch.unicode())
  40          {
  41          // Qt categorizes these as "Other_Format" not "Separator_Space"
  42          case 0x200B: // ZERO WIDTH SPACE
  43          case 0xFEFF: // ZERO WIDTH NO-BREAK SPACE
  44              removeChar = true;
  45              break;
  46          default:
  47              break;
  48          }
  49  
  50          // Remove whitespace
  51          if (ch.isSpace())
  52              removeChar = true;
  53  
  54          // To next character
  55          if (removeChar)
  56              input.remove(idx, 1);
  57          else
  58              ++idx;
  59      }
  60  
  61      // Validation
  62      QValidator::State state = QValidator::Acceptable;
  63      for (int idx = 0; idx < input.size(); ++idx)
  64      {
  65          int ch = input.at(idx).unicode();
  66  
  67          if (((ch >= '0' && ch<='9') ||
  68              (ch >= 'a' && ch<='z') ||
  69              (ch >= 'A' && ch<='Z')) &&
  70              ch != 'I' && ch != 'O') // Characters invalid in both Base58 and Bech32
  71          {
  72              // Alphanumeric and not a 'forbidden' character
  73          }
  74          else
  75          {
  76              state = QValidator::Invalid;
  77          }
  78      }
  79  
  80      return state;
  81  }
  82  
  83  BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) :
  84      QValidator(parent)
  85  {
  86  }
  87  
  88  QValidator::State BitcoinAddressCheckValidator::validate(QString &input, int &pos) const
  89  {
  90      Q_UNUSED(pos);
  91      // Validate the passed Bitcoin address
  92      if (IsValidDestinationString(input.toStdString())) {
  93          return QValidator::Acceptable;
  94      }
  95  
  96      return QValidator::Invalid;
  97  }
  98