if ( z_ret != Z_OK )
return File_Decomp_Error;
- if ( SessionPtr->Avail_Out == 0 )
+ if ( SessionPtr->Avail_Out == 0 and SessionPtr->Avail_In > 0)
return File_Decomp_BlockOut;
return File_Decomp_OK;
fd_status_t File_Decomp_ZIP(fd_session_t* SessionPtr)
{
uint8_t byte;
+ bool output_blocked = false;
if ( SessionPtr == nullptr )
return File_Decomp_Error;
{
// check if we read a local_header
if ( parser->local_header != ZIP_LOCAL_HEADER )
- return File_Decomp_Complete;
+ return output_blocked ? File_Decomp_BlockOut : File_Decomp_Complete;
// read a local_header, reset the index
parser->Index = 0;
if ( status == File_Decomp_BlockOut )
{
// ran out of output space
+ // Save this status because we need to return it to the inspector so it can alert
+ output_blocked = true;
if ( parser->data_descriptor )
{
// close the inflate stream
Move_N(SessionPtr, min);
// get more input
- return File_Decomp_BlockIn;
+ return output_blocked ? File_Decomp_BlockOut : File_Decomp_BlockIn;
}
if ( SessionPtr->Avail_Out < skip )
parser->Index++;
}
- return File_Decomp_BlockIn;
+ return output_blocked ? File_Decomp_BlockOut : File_Decomp_BlockIn;
}
HttpCommon::STAT_NOT_PRESENT };
int32_t publish_depth_remaining[2] = { HttpCommon::STAT_NOT_PRESENT,
HttpCommon::STAT_NOT_PRESENT };
+ int32_t file_decomp_buffer_size_remaining[2] = { HttpCommon::STAT_NOT_PRESENT,
+ HttpCommon::STAT_NOT_PRESENT };
uint64_t expected_trans_num[2] = { 1, 1 };
// number of user data octets seen so far (regular body or chunks)
msg_text.start() + partial_inspected_octets);
}
else
+ {
+ // First flush of inspection section - set full file decompress buffer size
+ session_data->file_decomp_buffer_size_remaining[source_id] =
+ FileService::decode_conf.get_decompress_buffer_size();
msg_text_new.set(msg_text);
+ }
int32_t& pub_depth_remaining = session_data->publish_depth_remaining[source_id];
if (pub_depth_remaining > 0)
if (partial_detect_length > 0)
{
- const int32_t total_length = partial_detect_length + decompressed_file_body.length();
+ const int32_t total_length = partial_detect_length +
+ decompressed_file_body.length();
+ assert(total_length <=
+ (int64_t)FileService::decode_conf.get_decompress_buffer_size());
uint8_t* const cumulative_buffer = new uint8_t[total_length];
memcpy(cumulative_buffer, partial_detect_buffer, partial_detect_length);
memcpy(cumulative_buffer + partial_detect_length, decompressed_file_body.start(),
output.set(input);
return;
}
- const uint32_t buffer_size = FileService::decode_conf.get_decompress_buffer_size();
+ const uint32_t buffer_size = session_data->file_decomp_buffer_size_remaining[source_id];
uint8_t* buffer = new uint8_t[buffer_size];
session_data->fd_alert_context.infractions = transaction->get_infractions(source_id);
session_data->fd_alert_context.events = session_data->events[source_id];
create_event(EVENT_FILE_DECOMPR_OVERRUN);
// Fall through
default:
- output.set(session_data->fd_state->Next_Out - buffer, buffer, true);
+ const uint32_t output_length = session_data->fd_state->Next_Out - buffer;
+ output.set(output_length, buffer, true);
+ assert((uint64_t)session_data->file_decomp_buffer_size_remaining[source_id] >=
+ output_length);
+ session_data->file_decomp_buffer_size_remaining[source_id] -= output_length;
break;
}
}