Fix Buffer Overflow

Fixes issue #509.
This commit is contained in:
jcdr428 2021-12-21 22:57:23 +01:00
parent 435f15224c
commit 3763dd3475
4 changed files with 96 additions and 76 deletions

View File

@ -106,47 +106,55 @@ HevcUnitWithProfile::HevcUnitWithProfile() : profile_idc(0), level_idc(0), inter
memset(sub_layer_profile_space, 0, sizeof(sub_layer_profile_space));
}
void HevcUnitWithProfile::profile_tier_level(int subLayers)
int HevcUnitWithProfile::profile_tier_level(int subLayers)
{
int profile_space = m_reader.getBits(2);
int tier_flag = m_reader.getBit();
profile_idc = m_reader.getBits(5);
m_reader.skipBits(32); // general_profile_compatibility_flag
int progressive_source_flag = m_reader.getBit();
interlaced_source_flag = m_reader.getBit();
int non_packed_constraint_flag = m_reader.getBit();
int frame_only_constraint_flag = m_reader.getBit();
m_reader.skipBits(32); // reserved_zero_44bits
m_reader.skipBits(12); // reserved_zero_44bits
level_idc = m_reader.getBits(8);
try
{
int profile_space = m_reader.getBits(2);
int tier_flag = m_reader.getBit();
profile_idc = m_reader.getBits(5);
m_reader.skipBits(32); // general_profile_compatibility_flag
int progressive_source_flag = m_reader.getBit();
interlaced_source_flag = m_reader.getBit();
int non_packed_constraint_flag = m_reader.getBit();
int frame_only_constraint_flag = m_reader.getBit();
m_reader.skipBits(32); // reserved_zero_44bits
m_reader.skipBits(12); // reserved_zero_44bits
level_idc = m_reader.getBits(8);
for (int i = 0; i < subLayers - 1; i++)
{
sub_layer_profile_present_flag[i] = m_reader.getBit();
sub_layer_level_present_flag[i] = m_reader.getBit();
}
if (subLayers > 1)
{
for (int i = subLayers - 1; i < 8; i++) m_reader.skipBits(2); // reserved_zero_2bits
}
for (int i = 0; i < subLayers - 1; i++)
{
if (sub_layer_profile_present_flag[i])
for (int i = 0; i < subLayers - 1; i++)
{
sub_layer_profile_space[i] = m_reader.getBits(2);
bool sub_layer_tier_flag = m_reader.getBit();
int sub_layer_profile_idc = m_reader.getBits(5);
for (int j = 0; j < 32; j++) m_reader.skipBit(); // sub_layer_profile_compatibility_flag[ i ][ j ] u(1)
m_reader.skipBit(); // sub_layer_progressive_source_flag[ i ] u(1)
m_reader.skipBit(); // sub_layer_interlaced_source_flag[ i ] u(1)
m_reader.skipBit(); // sub_layer_non_packed_constraint_flag[ i ] u(1)
m_reader.skipBit(); // sub_layer_frame_only_constraint_flag[ i ] u(1)
m_reader.skipBits(32); // sub_layer_reserved_zero_44bits
m_reader.skipBits(12); // sub_layer_reserved_zero_44bits
sub_layer_profile_present_flag[i] = m_reader.getBit();
sub_layer_level_present_flag[i] = m_reader.getBit();
}
if (sub_layer_level_present_flag[i])
m_reader.skipBits(8); // sub_layer_level_idc[ i ]
if (subLayers > 1)
{
for (int i = subLayers - 1; i < 8; i++) m_reader.skipBits(2); // reserved_zero_2bits
}
for (int i = 0; i < subLayers - 1; i++)
{
if (sub_layer_profile_present_flag[i])
{
sub_layer_profile_space[i] = m_reader.getBits(2);
bool sub_layer_tier_flag = m_reader.getBit();
int sub_layer_profile_idc = m_reader.getBits(5);
for (int j = 0; j < 32; j++) m_reader.skipBit(); // sub_layer_profile_compatibility_flag[ i ][ j ] u(1)
m_reader.skipBit(); // sub_layer_progressive_source_flag[ i ] u(1)
m_reader.skipBit(); // sub_layer_interlaced_source_flag[ i ] u(1)
m_reader.skipBit(); // sub_layer_non_packed_constraint_flag[ i ] u(1)
m_reader.skipBit(); // sub_layer_frame_only_constraint_flag[ i ] u(1)
m_reader.skipBits(32); // sub_layer_reserved_zero_44bits
m_reader.skipBits(12); // sub_layer_reserved_zero_44bits
}
if (sub_layer_level_present_flag[i])
m_reader.skipBits(8); // sub_layer_level_idc[ i ]
}
return 0;
}
catch (BitStreamException& e)
{
return NOT_ENOUGH_BUFFER;
}
}
@ -192,18 +200,18 @@ int HevcVpsUnit::deserialize()
if (rez)
return rez;
if (m_reader.getBitsLeft() < 128)
return NOT_ENOUGH_BUFFER;
try
{
vps_id = m_reader.getBits(4);
m_reader.skipBits(2); // reserved
vps_max_layers = m_reader.getBits(6) + 1;
vps_max_sub_layers = m_reader.getBits(3) + 1;
if (vps_max_sub_layers > 7)
return 1;
int vps_temporal_id_nesting_flag = m_reader.getBit();
m_reader.skipBits(16); // reserved
profile_tier_level(vps_max_sub_layers);
if (profile_tier_level(vps_max_sub_layers) != 0)
return 1;
bool vps_sub_layer_ordering_info_present_flag = m_reader.getBit();
for (int i = (vps_sub_layer_ordering_info_present_flag ? 0 : vps_max_sub_layers - 1);
@ -760,7 +768,8 @@ int HevcSpsUnit::deserialize()
return 1;
max_sub_layers = max_sub_layers_minus1 + 1;
int temporal_id_nesting_flag = m_reader.getBit();
profile_tier_level(max_sub_layers);
if (profile_tier_level(max_sub_layers) != 0)
return 1;
sps_id = extractUEGolombCode();
if (sps_id > 15)
return 1;

View File

@ -87,7 +87,7 @@ struct HevcUnitWithProfile : public HevcUnit
uint8_t sub_layer_profile_space[16];
protected:
void profile_tier_level(int subLayers);
int profile_tier_level(int subLayers);
};
struct HevcVpsUnit : public HevcUnitWithProfile

View File

@ -115,42 +115,50 @@ bool VvcUnit::dpb_parameters(int MaxSubLayersMinus1, bool subLayerInfoFlag)
VvcUnitWithProfile::VvcUnitWithProfile() : profile_idc(0), level_idc(0) {}
void VvcUnitWithProfile::profile_tier_level(bool profileTierPresentFlag, int MaxNumSubLayersMinus1)
int VvcUnitWithProfile::profile_tier_level(bool profileTierPresentFlag, int MaxNumSubLayersMinus1)
{
if (profileTierPresentFlag)
try
{
profile_idc = m_reader.getBits(7);
bool tier_flag = m_reader.getBit();
}
level_idc = m_reader.getBits(8);
m_reader.skipBits(2); // ptl_frame_only_constraint_flag, ptl_multilayer_enabled_flag
if (profileTierPresentFlag)
{ // general_constraints_info()
if (m_reader.getBit()) // gci_present_flag
if (profileTierPresentFlag)
{
m_reader.skipBits(32);
m_reader.skipBits(32);
m_reader.skipBits(7);
int gci_num_reserved_bits = m_reader.getBits(8);
for (int i = 0; i < gci_num_reserved_bits; i++) m_reader.skipBit(); // gci_reserved_zero_bit[i]
profile_idc = m_reader.getBits(7);
bool tier_flag = m_reader.getBit();
}
m_reader.skipBits(m_reader.getBitsLeft() % 8); // gci_alignment_zero_bit
level_idc = m_reader.getBits(8);
m_reader.skipBits(2); // ptl_frame_only_constraint_flag, ptl_multilayer_enabled_flag
if (profileTierPresentFlag)
{ // general_constraints_info()
if (m_reader.getBit()) // gci_present_flag
{
m_reader.skipBits(32);
m_reader.skipBits(32);
m_reader.skipBits(7);
int gci_num_reserved_bits = m_reader.getBits(8);
for (int i = 0; i < gci_num_reserved_bits; i++) m_reader.skipBit(); // gci_reserved_zero_bit[i]
}
m_reader.skipBits(m_reader.getBitsLeft() % 8); // gci_alignment_zero_bit
}
std::vector<int> ptl_sublayer_level_present_flag;
ptl_sublayer_level_present_flag.resize(MaxNumSubLayersMinus1);
for (int i = MaxNumSubLayersMinus1 - 1; i >= 0; i--) ptl_sublayer_level_present_flag[i] = m_reader.getBit();
m_reader.skipBits(m_reader.getBitsLeft() % 8); // ptl_reserved_zero_bit
for (int i = MaxNumSubLayersMinus1 - 1; i >= 0; i--)
if (ptl_sublayer_level_present_flag[i])
m_reader.skipBits(8); // sublayer_level_idc[i]
if (profileTierPresentFlag)
{
int ptl_num_sub_profiles = m_reader.getBits(8);
for (int i = 0; i < ptl_num_sub_profiles; i++) m_reader.skipBits(32); // general_sub_profile_idc[i]
}
return 0;
}
std::vector<int> ptl_sublayer_level_present_flag;
ptl_sublayer_level_present_flag.resize(MaxNumSubLayersMinus1);
for (int i = MaxNumSubLayersMinus1 - 1; i >= 0; i--) ptl_sublayer_level_present_flag[i] = m_reader.getBit();
m_reader.skipBits(m_reader.getBitsLeft() % 8); // ptl_reserved_zero_bit
for (int i = MaxNumSubLayersMinus1 - 1; i >= 0; i--)
if (ptl_sublayer_level_present_flag[i])
m_reader.skipBits(8); // sublayer_level_idc[i]
if (profileTierPresentFlag)
catch (BitStreamException& e)
{
int ptl_num_sub_profiles = m_reader.getBits(8);
for (int i = 0; i < ptl_num_sub_profiles; i++) m_reader.skipBits(32); // general_sub_profile_idc[i]
return NOT_ENOUGH_BUFFER;
}
}
@ -270,7 +278,9 @@ int VvcVpsUnit::deserialize()
m_reader.skipBits(m_reader.getBitsLeft() % 8); // vps_ptl_alignment_zero_bit
for (int i = 0; i < vps_num_ptls; i++) profile_tier_level(vps_pt_present_flag[i], vps_ptl_max_tid[i]);
for (int i = 0; i < vps_num_ptls; i++)
if (profile_tier_level(vps_pt_present_flag[i], vps_ptl_max_tid[i]) != 0)
return 1;
for (int i = 0; i < TotalNumOlss; i++)
if (vps_num_ptls > 1 && vps_num_ptls != TotalNumOlss)
@ -444,7 +454,8 @@ int VvcSpsUnit::deserialize()
if (sps_id == 0 && !sps_ptl_dpb_hrd_params_present_flag)
return 1;
if (sps_ptl_dpb_hrd_params_present_flag)
profile_tier_level(1, max_sublayers_minus1);
if (profile_tier_level(1, max_sublayers_minus1) != 0)
return 1;
m_reader.skipBit(); // sps_gdr_enabled_flag
if (m_reader.getBit()) // sps_ref_pic_resampling_enabled_flag
m_reader.skipBit(); // sps_res_change_in_clvs_allowed_flag

View File

@ -74,7 +74,7 @@ struct VvcUnitWithProfile : public VvcUnit
int level_idc;
protected:
void profile_tier_level(bool profileTierPresentFlag, int MaxNumSubLayersMinus1);
int profile_tier_level(bool profileTierPresentFlag, int MaxNumSubLayersMinus1);
};
struct VvcHrdUnit : public VvcUnit