Determine if 'scriptPubKey' is a TX_NULL_DATA script, and fill 'result' with (digests of) the push data opcodes. * If 'scriptPubKey' isn't a TX_NULL_DATA, then 'result->op' is set to NULL. * Otherwise '*result' is set to '(parsedNullData){ .op = *allocation, .len = countNullDataCodes(scriptPubKey) }. * and then the 'opcode result->op[result->len]' array is filled in with (digests of) the pus da
| 187 | * countNullDataCodes(scriptPubKey) <= *allocationLen |
| 188 | */ |
| 189 | static void parseNullData(parsedNullData* result, opcode** allocation, size_t* allocationLen, const rawElementsBuffer* scriptPubKey) { |
| 190 | *result = (parsedNullData){ .op = *allocation }; |
| 191 | |
| 192 | if (0 == scriptPubKey->len || 0x6a != scriptPubKey->buf[0] ) { result->op = NULL; return; } |
| 193 | |
| 194 | for (uint_fast32_t i = 1; i < scriptPubKey->len; ++result->len) { |
| 195 | unsigned char code = scriptPubKey->buf[i++]; |
| 196 | if (*allocationLen <= result->len || 0x60 < code) { result->op = NULL; return; } |
| 197 | if (0x4f <= code) { |
| 198 | (*allocation)[result->len].code = OP_1NEGATE + (code - 0x4f); |
| 199 | } else { |
| 200 | uint_fast32_t skip = 0; |
| 201 | if (code < 0x4c) { |
| 202 | skip = code; |
| 203 | (*allocation)[result->len].code = OP_IMMEDIATE; |
| 204 | } else { |
| 205 | if (scriptPubKey->len == i) { result->op = NULL; return; } |
| 206 | skip = scriptPubKey->buf[i++]; |
| 207 | if (code < 0x4d) { |
| 208 | (*allocation)[result->len].code = OP_PUSHDATA; |
| 209 | } else { |
| 210 | if (scriptPubKey->len == i) { result->op = NULL; return; } |
| 211 | skip += (uint_fast32_t)(scriptPubKey->buf[i++]) << 8; |
| 212 | if (code < 0x4e) { |
| 213 | (*allocation)[result->len].code = OP_PUSHDATA2; |
| 214 | } else { |
| 215 | if (scriptPubKey->len == i) { result->op = NULL; return; } |
| 216 | skip += (uint_fast32_t)(scriptPubKey->buf[i++]) << 16; |
| 217 | if (scriptPubKey->len == i) { result->op = NULL; return; } |
| 218 | skip += (uint_fast32_t)(scriptPubKey->buf[i++]) << 24; |
| 219 | (*allocation)[result->len].code = OP_PUSHDATA4; |
| 220 | } |
| 221 | } |
| 222 | } |
| 223 | if (scriptPubKey->len - i < skip) { result->op = NULL; return; } |
| 224 | { |
| 225 | sha256_context ctx = sha256_init((*allocation)[result->len].dataHash.s); |
| 226 | sha256_uchars(&ctx, &scriptPubKey->buf[i], skip); |
| 227 | sha256_finalize(&ctx); |
| 228 | } |
| 229 | i += skip; |
| 230 | } |
| 231 | } |
| 232 | *allocation += result->len; /* C requires '*allocation != NULL', even when 'result->len == 0'. */ |
| 233 | *allocationLen -= result->len; |
| 234 | } |
| 235 | |
| 236 | /* Initialize a 'sigOutput' from a 'rawElementsOutput', copying or hashing the data as needed. |
| 237 | * |
no test coverage detected