| 57 | } // namespace |
| 58 | |
| 59 | CScript ParseScript(const std::string &s) { |
| 60 | CScript result; |
| 61 | |
| 62 | std::vector<std::string> words = SplitString(s, " \t\n"); |
| 63 | |
| 64 | size_t push_size = 0, next_push_size = 0; |
| 65 | size_t script_size = 0; |
| 66 | // Deal with PUSHDATA1 operation with some more hacks. |
| 67 | size_t push_data_size = 0; |
| 68 | |
| 69 | for (const auto &w : words) { |
| 70 | if (w.empty()) { |
| 71 | // Empty string, ignore. (SplitString doesn't combine multiple |
| 72 | // separators) |
| 73 | continue; |
| 74 | } |
| 75 | |
| 76 | // Update script size. |
| 77 | script_size = result.size(); |
| 78 | |
| 79 | // Make sure we keep track of the size of push operations. |
| 80 | push_size = next_push_size; |
| 81 | next_push_size = 0; |
| 82 | |
| 83 | // Decimal numbers |
| 84 | if (std::all_of(w.begin(), w.end(), ::IsDigit) || |
| 85 | (w.front() == '-' && w.size() > 1 && |
| 86 | std::all_of(w.begin() + 1, w.end(), ::IsDigit))) { |
| 87 | // Number |
| 88 | const auto num{ToIntegral<int64_t>(w)}; |
| 89 | |
| 90 | // Limit the range of numbers ParseScript accepts in decimal |
| 91 | // since numbers outside -0x7FFFFFFFFFFFFFFF...0x7FFFFFFFFFFFFFFF |
| 92 | // are illegal in scripts. |
| 93 | // This means, only the int64_t -0x8000000000000000 is illegal. |
| 94 | if (!num.has_value() || |
| 95 | num == std::numeric_limits<int64_t>::min()) { |
| 96 | throw std::runtime_error( |
| 97 | "script parse error: decimal numeric value only allowed in " |
| 98 | "the range -0x7FFFFFFFFFFFFFFF...0x7FFFFFFFFFFFFFFF"); |
| 99 | } |
| 100 | |
| 101 | result << num.value(); |
| 102 | goto next; |
| 103 | } |
| 104 | |
| 105 | // Hex Data |
| 106 | if (w.substr(0, 2) == "0x" && w.size() > 2) { |
| 107 | if (!IsHex(std::string(w.begin() + 2, w.end()))) { |
| 108 | // Should only arrive here for improperly formatted hex values |
| 109 | throw std::runtime_error("Hex numbers expected to be formatted " |
| 110 | "in full-byte chunks (ex: 0x00 " |
| 111 | "instead of 0x0)"); |
| 112 | } |
| 113 | |
| 114 | // Raw hex data, inserted NOT pushed onto stack: |
| 115 | std::vector<uint8_t> raw = |
| 116 | ParseHex(std::string(w.begin() + 2, w.end())); |
no test coverage detected