| 158 | } |
| 159 | |
| 160 | Error GDScriptV2TokenizerBufferCompat::set_code_buffer(const Vector<uint8_t> &p_buffer) { |
| 161 | const uint8_t *buf = p_buffer.ptr(); |
| 162 | ERR_FAIL_COND_V(p_buffer.size() < 12 || p_buffer[0] != 'G' || p_buffer[1] != 'D' || p_buffer[2] != 'S' || p_buffer[3] != 'C', ERR_INVALID_DATA); |
| 163 | |
| 164 | int version = decode_uint32(&buf[4]); |
| 165 | ERR_FAIL_COND_V_MSG(version > decomp->get_bytecode_version(), ERR_INVALID_DATA, "Binary GDScript is too recent! Please use a newer engine version."); |
| 166 | |
| 167 | int decompressed_size = decode_uint32(&buf[8]); |
| 168 | |
| 169 | Vector<uint8_t> contents; |
| 170 | if (decompressed_size == 0) { |
| 171 | contents = p_buffer.slice(12); |
| 172 | } else { |
| 173 | contents.resize(decompressed_size); |
| 174 | int result = Compression::decompress(contents.ptrw(), contents.size(), &buf[12], p_buffer.size() - 12, Compression::MODE_ZSTD); |
| 175 | ERR_FAIL_COND_V_MSG(result != decompressed_size, ERR_INVALID_DATA, "Error decompressing GDScript tokenizer buffer."); |
| 176 | } |
| 177 | |
| 178 | int total_len = contents.size(); |
| 179 | buf = contents.ptr(); |
| 180 | const int token_count_offset = version < GDScriptDecomp::CONTENT_HEADER_SIZE_CHANGED ? 16 : 12; |
| 181 | const int content_header_size = token_count_offset + 4; |
| 182 | uint32_t identifier_count = decode_uint32(&buf[0]); |
| 183 | uint32_t constant_count = decode_uint32(&buf[4]); |
| 184 | uint32_t token_line_count = decode_uint32(&buf[8]); |
| 185 | uint32_t token_count = decode_uint32(&buf[token_count_offset]); |
| 186 | |
| 187 | const uint8_t *b = &buf[content_header_size]; |
| 188 | total_len -= content_header_size; |
| 189 | |
| 190 | identifiers.resize(identifier_count); |
| 191 | for (uint32_t i = 0; i < identifier_count; i++) { |
| 192 | uint32_t len = decode_uint32(b); |
| 193 | total_len -= 4; |
| 194 | ERR_FAIL_COND_V((len * 4u) > (uint32_t)total_len, ERR_INVALID_DATA); |
| 195 | b += 4; |
| 196 | Vector<uint32_t> cs; |
| 197 | cs.resize(len); |
| 198 | for (uint32_t j = 0; j < len; j++) { |
| 199 | uint8_t tmp[4]; |
| 200 | for (uint32_t k = 0; k < 4; k++) { |
| 201 | tmp[k] = b[j * 4 + k] ^ 0xb6; |
| 202 | } |
| 203 | cs.write[j] = decode_uint32(tmp); |
| 204 | } |
| 205 | |
| 206 | String s = String::utf32(Span(reinterpret_cast<const char32_t *>(cs.ptr()), len)); |
| 207 | b += len * 4; |
| 208 | total_len -= len * 4; |
| 209 | identifiers.write[i] = s; |
| 210 | } |
| 211 | |
| 212 | constants.resize(constant_count); |
| 213 | for (uint32_t i = 0; i < constant_count; i++) { |
| 214 | Variant v; |
| 215 | int len; |
| 216 | Error err = decode_variant(v, b, total_len, &len, false); |
| 217 | if (err) { |
no test coverage detected