| 192 | #define CHECK_GDSC_HEADER(p_buffer) _GDRE_CHECK_HEADER(p_buffer, GDSC_HEADER) |
| 193 | |
| 194 | Error GDScriptDecomp::get_ids_consts_tokens_v2(const Vector<uint8_t> &p_buffer, Vector<StringName> &identifiers, Vector<Variant> &constants, Vector<uint32_t> &tokens, HashMap<uint32_t, uint32_t> &lines, HashMap<uint32_t, uint32_t> &end_lines, HashMap<uint32_t, uint32_t> &columns) { |
| 195 | const uint8_t *buf = p_buffer.ptr(); |
| 196 | GDSDECOMP_FAIL_COND_V_MSG(p_buffer.size() < 12 || !CHECK_GDSC_HEADER(p_buffer), ERR_INVALID_DATA, "Invalid GDScript tokenizer buffer."); |
| 197 | |
| 198 | int version = decode_uint32(&buf[4]); |
| 199 | GDSDECOMP_FAIL_COND_V_MSG(version > LATEST_GDSCRIPT_VERSION, ERR_INVALID_DATA, "Binary GDScript is too recent! Please use a newer engine version."); |
| 200 | GDSDECOMP_FAIL_COND_V_MSG(version < GDSCRIPT_2_0_VERSION, ERR_INVALID_DATA, "Don't use this function for older versions of GDScript."); |
| 201 | |
| 202 | int decompressed_size = decode_uint32(&buf[8]); |
| 203 | |
| 204 | Vector<uint8_t> contents; |
| 205 | GDSDECOMP_FAIL_COND_V_MSG(decompress_buf(p_buffer, contents) != decompressed_size, ERR_INVALID_DATA, "Error decompressing GDScript tokenizer buffer."); |
| 206 | |
| 207 | int total_len = contents.size(); |
| 208 | buf = contents.ptr(); |
| 209 | const int token_count_offset = version < CONTENT_HEADER_SIZE_CHANGED ? 16 : 12; |
| 210 | const int content_header_size = token_count_offset + 4; |
| 211 | uint32_t identifier_count = decode_uint32(&buf[0]); |
| 212 | uint32_t constant_count = decode_uint32(&buf[4]); |
| 213 | uint32_t token_line_count = decode_uint32(&buf[8]); |
| 214 | uint32_t token_count = decode_uint32(&buf[token_count_offset]); |
| 215 | |
| 216 | const uint8_t *b = &buf[content_header_size]; |
| 217 | total_len -= content_header_size; |
| 218 | |
| 219 | identifiers.resize(identifier_count); |
| 220 | for (uint32_t i = 0; i < identifier_count; i++) { |
| 221 | uint32_t len = decode_uint32(b); |
| 222 | total_len -= 4; |
| 223 | GDSDECOMP_FAIL_COND_V_MSG((len * 4u) > (uint32_t)total_len, ERR_INVALID_DATA, "Invalid identifier length."); |
| 224 | b += 4; |
| 225 | Vector<uint32_t> cs; |
| 226 | cs.resize(len); |
| 227 | for (uint32_t j = 0; j < len; j++) { |
| 228 | uint8_t tmp[4]; |
| 229 | for (uint32_t k = 0; k < 4; k++) { |
| 230 | tmp[k] = b[j * 4 + k] ^ 0xb6; |
| 231 | } |
| 232 | cs.write[j] = decode_uint32(tmp); |
| 233 | } |
| 234 | String s = String::utf32({ reinterpret_cast<const char32_t *>(cs.ptr()), len }); |
| 235 | b += len * 4; |
| 236 | total_len -= len * 4; |
| 237 | identifiers.write[i] = StringName(s); |
| 238 | } |
| 239 | |
| 240 | constants.resize(constant_count); |
| 241 | for (uint32_t i = 0; i < constant_count; i++) { |
| 242 | Variant v; |
| 243 | int len; |
| 244 | Error err = VariantDecoderCompat::decode_variant_compat(get_variant_ver_major(), v, b, total_len, &len); |
| 245 | if (err) { |
| 246 | return err; |
| 247 | } |
| 248 | b += len; |
| 249 | total_len -= len; |
| 250 | constants.write[i] = v; |
| 251 | } |
nothing calls this directly
no test coverage detected