univalue_get.cpp raw

   1  // Copyright 2014 BitPay Inc.
   2  // Copyright 2015 Bitcoin Core Developers
   3  // Distributed under the MIT software license, see the accompanying
   4  // file COPYING or https://opensource.org/licenses/mit-license.php.
   5  
   6  #include <univalue.h>
   7  
   8  #include <cstring>
   9  #include <locale>
  10  #include <optional>
  11  #include <sstream>
  12  #include <stdexcept>
  13  #include <string>
  14  #include <vector>
  15  
  16  namespace
  17  {
  18  static bool ParsePrechecks(const std::string& str)
  19  {
  20      if (str.empty()) // No empty string allowed
  21          return false;
  22      if (str.size() >= 1 && (json_isspace(str[0]) || json_isspace(str[str.size()-1]))) // No padding allowed
  23          return false;
  24      if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
  25          return false;
  26      return true;
  27  }
  28  
  29  std::optional<double> ParseDouble(const std::string& str)
  30  {
  31      if (!ParsePrechecks(str))
  32          return std::nullopt;
  33      if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
  34          return std::nullopt;
  35      std::istringstream text(str);
  36      text.imbue(std::locale::classic());
  37      double result;
  38      text >> result;
  39      if (!text.eof() || text.fail()) {
  40          return std::nullopt;
  41      }
  42      return result;
  43  }
  44  }
  45  
  46  const std::vector<std::string>& UniValue::getKeys() const
  47  {
  48      checkType(VOBJ);
  49      return keys;
  50  }
  51  
  52  const std::vector<UniValue>& UniValue::getValues() const
  53  {
  54      if (typ != VOBJ && typ != VARR)
  55          throw std::runtime_error("JSON value is not an object or array as expected");
  56      return values;
  57  }
  58  
  59  bool UniValue::get_bool() const
  60  {
  61      checkType(VBOOL);
  62      return isTrue();
  63  }
  64  
  65  const std::string& UniValue::get_str() const
  66  {
  67      checkType(VSTR);
  68      return getValStr();
  69  }
  70  
  71  double UniValue::get_real() const
  72  {
  73      checkType(VNUM);
  74      if (const auto retval{ParseDouble(getValStr())}) {
  75          return *retval;
  76      }
  77      throw std::runtime_error("JSON double out of range");
  78  }
  79  
  80  const UniValue& UniValue::get_obj() const
  81  {
  82      checkType(VOBJ);
  83      return *this;
  84  }
  85  
  86  const UniValue& UniValue::get_array() const
  87  {
  88      checkType(VARR);
  89      return *this;
  90  }
  91