[APU] Resolved crashes related to out of bound readouts

This commit is contained in:
Gliniak 2022-11-01 11:24:01 +01:00
parent 55877f4c61
commit c080e2e17c
2 changed files with 20 additions and 16 deletions

View file

@ -402,6 +402,11 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
break; break;
} }
if (is_stream_done_) {
is_stream_done_ = false;
SwapInputBuffer(data);
return;
}
// Setup the input buffer if we are at loop_end. // Setup the input buffer if we are at loop_end.
// The input buffer must not be swapped out until all loops are processed. // The input buffer must not be swapped out until all loops are processed.
reuse_input_buffer = TrySetupNextLoop(data, false); reuse_input_buffer = TrySetupNextLoop(data, false);
@ -418,9 +423,11 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
BitStream stream(current_input_buffer, current_input_size * 8); BitStream stream(current_input_buffer, current_input_size * 8);
stream.SetOffset(data->input_buffer_read_offset); stream.SetOffset(data->input_buffer_read_offset);
if (data->input_buffer_read_offset == current_input_size * 8) { if (data->input_buffer_read_offset > current_input_size * 8) {
SwapInputBuffer(data); XELOGE(
return; "XmaContext {}: Error - Provided input offset exceed input buffer "
"size! ({} > {})",
id(), data->input_buffer_read_offset, current_input_size * 8);
} }
// if we had a buffer swap try to skip packets first // if we had a buffer swap try to skip packets first
if (packets_skip_ > 0) { if (packets_skip_ > 0) {
@ -436,7 +443,7 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
reuse_input_buffer = TrySetupNextLoop(data, true); reuse_input_buffer = TrySetupNextLoop(data, true);
} }
if (!reuse_input_buffer) { if (!reuse_input_buffer) {
SwapInputBuffer(data); is_stream_done_ = true;
} }
return; return;
} }
@ -574,7 +581,7 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
reuse_input_buffer = TrySetupNextLoop(data, true); reuse_input_buffer = TrySetupNextLoop(data, true);
} }
if (!reuse_input_buffer) { if (!reuse_input_buffer) {
SwapInputBuffer(data); is_stream_done_ = true;
} }
return; return;
} }
@ -656,16 +663,17 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
while (packets_skip_ > 0) { while (packets_skip_ > 0) {
packets_skip_--; packets_skip_--;
packet_idx++; packet_idx++;
if (packet_idx > current_input_packet_count) { if (packet_idx >= current_input_packet_count) {
if (!reuse_input_buffer) { if (!reuse_input_buffer) {
// Last packet. Try setup once more. // Last packet. Try setup once more.
reuse_input_buffer = TrySetupNextLoop(data, true); reuse_input_buffer = TrySetupNextLoop(data, true);
} }
if (!reuse_input_buffer) { if (!reuse_input_buffer) {
SwapInputBuffer(data); is_stream_done_ = true;
if (output_rb.write_offset() == output_rb.read_offset()) {
data->output_buffer_valid = 0;
}
} }
data->input_buffer_read_offset =
std::max(kBitsPerHeader, data->input_buffer_read_offset);
return; return;
} }
} }
@ -675,26 +683,21 @@ void XmaContext::Decode(XMA_CONTEXT_DATA* data) {
} }
if (offset == 0 || frame_idx == -1) { if (offset == 0 || frame_idx == -1) {
// Next packet but we already skipped to it // Next packet but we already skipped to it
if (packet_idx > current_input_packet_count) { if (packet_idx >= current_input_packet_count) {
// Buffer is fully used // Buffer is fully used
if (!reuse_input_buffer) { if (!reuse_input_buffer) {
// Last packet. Try setup once more. // Last packet. Try setup once more.
reuse_input_buffer = TrySetupNextLoop(data, true); reuse_input_buffer = TrySetupNextLoop(data, true);
} }
if (!reuse_input_buffer) { if (!reuse_input_buffer) {
SwapInputBuffer(data); is_stream_done_ = true;
} }
data->input_buffer_read_offset =
std::max(kBitsPerHeader, data->input_buffer_read_offset);
break; break;
} }
offset = offset =
xma::GetPacketFrameOffset(packet) + packet_idx * kBitsPerPacket; xma::GetPacketFrameOffset(packet) + packet_idx * kBitsPerPacket;
} }
// TODO buffer bounds check // TODO buffer bounds check
if (offset >= (current_input_size << 3)) {
offset = uint32_t(current_input_size << 3);
}
assert_true(data->input_buffer_read_offset < offset); assert_true(data->input_buffer_read_offset < offset);
data->input_buffer_read_offset = offset; data->input_buffer_read_offset = offset;
} }

View file

@ -221,6 +221,7 @@ class XmaContext {
// std::vector<uint8_t> partial_frame_buffer_; // std::vector<uint8_t> partial_frame_buffer_;
uint32_t packets_skip_ = 0; uint32_t packets_skip_ = 0;
bool is_stream_done_ = false;
// bool split_frame_pending_ = false; // bool split_frame_pending_ = false;
uint32_t split_frame_len_ = 0; uint32_t split_frame_len_ = 0;
uint32_t split_frame_len_partial_ = 0; uint32_t split_frame_len_partial_ = 0;