Commit adfc3c25 for libheif
commit adfc3c25fe4e7e5114a2c7b6398d3ecdf376131e
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Fri May 15 22:05:52 2026 +0200
check all get_uvlc() calls for errors (#1785)
diff --git a/libheif/codecs/avc_boxes.cc b/libheif/codecs/avc_boxes.cc
index 16033fb6..363c11ee 100644
--- a/libheif/codecs/avc_boxes.cc
+++ b/libheif/codecs/avc_boxes.cc
@@ -362,15 +362,15 @@ Error parse_sps_for_avcC_configuration(const uint8_t* sps, size_t size,
config->AVCLevelIndication = reader.get_bits8(8);
config->lengthSize = 4;
- uint32_t value;
- reader.get_uvlc(&value); // SPS ID
-
Error invalidUVLC{
heif_error_Invalid_input,
heif_suberror_Unspecified,
"Invalid variable length code in AVC SPS header"
};
+ uint32_t value;
+ if (!reader.get_uvlc(&value)) { return invalidUVLC; } // SPS ID
+
if (std::set<int>{100, 110, 122, 244, 44, 83, 86}.contains(config->AVCProfileIndication)) {
if (!reader.get_uvlc(&value)) {
return invalidUVLC;
@@ -413,31 +413,33 @@ Error parse_sps_for_avcC_configuration(const uint8_t* sps, size_t size,
config->bit_depth_chroma = 8;
}
- reader.get_uvlc(&value); // log2_max_frame_num_minus4
+ if (!reader.get_uvlc(&value)) { return invalidUVLC; } // log2_max_frame_num_minus4
uint32_t pic_order_cnt_type;
- reader.get_uvlc(&pic_order_cnt_type);
+ if (!reader.get_uvlc(&pic_order_cnt_type)) { return invalidUVLC; }
if (pic_order_cnt_type == 0) {
- reader.get_uvlc(&value);
+ if (!reader.get_uvlc(&value)) { return invalidUVLC; }
}
else if (pic_order_cnt_type == 1) {
reader.get_bits(1);
int32_t svalue;
- reader.get_svlc(&svalue);
- reader.get_svlc(&svalue);
+ if (!reader.get_svlc(&svalue) ||
+ !reader.get_svlc(&svalue)) { return invalidUVLC; }
uint32_t num_ref_franes_in_pic_order_cnt_cycle;
- reader.get_uvlc(&num_ref_franes_in_pic_order_cnt_cycle);
+ if (!reader.get_uvlc(&num_ref_franes_in_pic_order_cnt_cycle)) { return invalidUVLC; }
for (uint32_t i = 0; i < num_ref_franes_in_pic_order_cnt_cycle; i++) {
- reader.get_uvlc(&value);
+ if (!reader.get_uvlc(&value)) { return invalidUVLC; }
}
}
- reader.get_uvlc(&value); // num_ref_frames
+ if (!reader.get_uvlc(&value)) { return invalidUVLC; } // num_ref_frames
reader.skip_bits(1);
uint32_t pic_width_in_mbs_minus1;
uint32_t pic_height_in_mbs_minus1;
- reader.get_uvlc(&pic_width_in_mbs_minus1);
- reader.get_uvlc(&pic_height_in_mbs_minus1);
+ if (!reader.get_uvlc(&pic_width_in_mbs_minus1) ||
+ !reader.get_uvlc(&pic_height_in_mbs_minus1)) {
+ return invalidUVLC;
+ }
*width = (pic_width_in_mbs_minus1 + 1) * 16;
*height = (pic_height_in_mbs_minus1 + 1) * 16;
@@ -455,10 +457,12 @@ Error parse_sps_for_avcC_configuration(const uint8_t* sps, size_t size,
uint32_t frame_cropping_flag = reader.get_bits(1);
if (frame_cropping_flag) {
uint32_t left, right, top, bottom;
- reader.get_uvlc(&left);
- reader.get_uvlc(&right);
- reader.get_uvlc(&top);
- reader.get_uvlc(&bottom);
+ if (!reader.get_uvlc(&left) ||
+ !reader.get_uvlc(&right) ||
+ !reader.get_uvlc(&top) ||
+ !reader.get_uvlc(&bottom)) {
+ return invalidUVLC;
+ }
*width -= left + right;
*height -= top + bottom;
diff --git a/libheif/codecs/hevc_boxes.cc b/libheif/codecs/hevc_boxes.cc
index 9ca1f111..0ff74e89 100644
--- a/libheif/codecs/hevc_boxes.cc
+++ b/libheif/codecs/hevc_boxes.cc
@@ -658,18 +658,27 @@ Error parse_sps_for_hvcC_configuration(const uint8_t* sps, size_t size,
// --- SPS continued ---
- uint32_t dummy, value;
- reader.get_uvlc(&dummy); // skip seq_parameter_seq_id
+ Error invalidUVLC{
+ heif_error_Invalid_input,
+ heif_suberror_Invalid_parameter_value,
+ "Invalid variable length code in HEVC SPS header"
+ };
- reader.get_uvlc(&value);
+ uint32_t dummy, value;
+ if (!reader.get_uvlc(&dummy) || // skip seq_parameter_seq_id
+ !reader.get_uvlc(&value)) {
+ return invalidUVLC;
+ }
config->chroma_format = (uint8_t) value;
if (config->chroma_format == 3) {
reader.skip_bits(1);
}
- reader.get_uvlc(width);
- reader.get_uvlc(height);
+ if (!reader.get_uvlc(width) ||
+ !reader.get_uvlc(height)) {
+ return invalidUVLC;
+ }
if (coded_size) {
coded_size->width = *width;
@@ -679,10 +688,12 @@ Error parse_sps_for_hvcC_configuration(const uint8_t* sps, size_t size,
bool conformance_window = reader.get_bits(1);
if (conformance_window) {
uint32_t left, right, top, bottom;
- reader.get_uvlc(&left);
- reader.get_uvlc(&right);
- reader.get_uvlc(&top);
- reader.get_uvlc(&bottom);
+ if (!reader.get_uvlc(&left) ||
+ !reader.get_uvlc(&right) ||
+ !reader.get_uvlc(&top) ||
+ !reader.get_uvlc(&bottom)) {
+ return invalidUVLC;
+ }
//printf("conformance borders: %u %u %u %u\n",left,right,top,bottom);
@@ -704,7 +715,9 @@ Error parse_sps_for_hvcC_configuration(const uint8_t* sps, size_t size,
*height -= (uint32_t)crop_h;
}
- reader.get_uvlc(&value);
+ if (!reader.get_uvlc(&value)) {
+ return invalidUVLC;
+ }
if (value > 8) {
return Error{heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
@@ -712,7 +725,9 @@ Error parse_sps_for_hvcC_configuration(const uint8_t* sps, size_t size,
}
config->bit_depth_luma = (uint8_t) (value + 8);
- reader.get_uvlc(&value);
+ if (!reader.get_uvlc(&value)) {
+ return invalidUVLC;
+ }
if (value > 8) {
return Error{heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
diff --git a/libheif/codecs/vvc_boxes.cc b/libheif/codecs/vvc_boxes.cc
index 0a531514..9bf300d8 100644
--- a/libheif/codecs/vvc_boxes.cc
+++ b/libheif/codecs/vvc_boxes.cc
@@ -500,14 +500,19 @@ Error parse_sps_for_vvcC_configuration(const uint8_t* sps, size_t size,
reader.skip_bits(1); // sps_res_change_in_clvs_allowed_flag
}
+ Error invalidUVLC{
+ heif_error_Invalid_input,
+ heif_suberror_Invalid_parameter_value,
+ "Invalid variable length code in VVC SPS header"
+ };
+
uint32_t sps_pic_width_max_in_luma_samples;
uint32_t sps_pic_height_max_in_luma_samples;
- bool success;
- success = reader.get_uvlc(&sps_pic_width_max_in_luma_samples);
- (void)success;
- success = reader.get_uvlc(&sps_pic_height_max_in_luma_samples);
- (void)success;
+ if (!reader.get_uvlc(&sps_pic_width_max_in_luma_samples) ||
+ !reader.get_uvlc(&sps_pic_height_max_in_luma_samples)) {
+ return invalidUVLC;
+ }
*width = sps_pic_width_max_in_luma_samples;
*height = sps_pic_height_max_in_luma_samples;
@@ -530,10 +535,12 @@ Error parse_sps_for_vvcC_configuration(const uint8_t* sps, size_t size,
int sps_conformance_window_flag = reader.get_bits(1);
if (sps_conformance_window_flag) {
uint32_t left, right, top, bottom;
- reader.get_uvlc(&left);
- reader.get_uvlc(&right);
- reader.get_uvlc(&top);
- reader.get_uvlc(&bottom);
+ if (!reader.get_uvlc(&left) ||
+ !reader.get_uvlc(&right) ||
+ !reader.get_uvlc(&top) ||
+ !reader.get_uvlc(&bottom)) {
+ return invalidUVLC;
+ }
// SubWidthC / SubHeightC per ITU-T H.266 Table 5-1, indexed by chroma_format_idc.
uint32_t subWidthC = 1, subHeightC = 1;
@@ -560,8 +567,9 @@ Error parse_sps_for_vvcC_configuration(const uint8_t* sps, size_t size,
}
uint32_t bitDepth_minus8;
- success = reader.get_uvlc(&bitDepth_minus8);
- (void)success;
+ if (!reader.get_uvlc(&bitDepth_minus8)) {
+ return invalidUVLC;
+ }
if (bitDepth_minus8 > 0xFF - 8) {
return {heif_error_Encoding_error, heif_suberror_Unspecified, "VCC bit depth out of range."};
diff --git a/libheif/plugins/decoder_webcodecs.cc b/libheif/plugins/decoder_webcodecs.cc
index 692180c2..bda1e562 100644
--- a/libheif/plugins/decoder_webcodecs.cc
+++ b/libheif/plugins/decoder_webcodecs.cc
@@ -269,26 +269,37 @@ Error parse_sps_for_hvcC_configuration2(const uint8_t* sps, size_t size,
// --- SPS continued ---
- uint32_t dummy, value;
- reader.get_uvlc(&dummy); // skip seq_parameter_seq_id
+ Error invalidUVLC{
+ heif_error_Invalid_input,
+ heif_suberror_Invalid_parameter_value,
+ "Invalid variable length code in HEVC SPS header"
+ };
- reader.get_uvlc(&value);
+ uint32_t dummy, value;
+ if (!reader.get_uvlc(&dummy) || // skip seq_parameter_seq_id
+ !reader.get_uvlc(&value)) {
+ return invalidUVLC;
+ }
config->chroma_format = (uint8_t) value;
if (config->chroma_format == 3) {
reader.skip_bits(1);
}
- reader.get_uvlc(width);
- reader.get_uvlc(height);
+ if (!reader.get_uvlc(width) ||
+ !reader.get_uvlc(height)) {
+ return invalidUVLC;
+ }
bool conformance_window = reader.get_bits(1);
if (conformance_window) {
uint32_t left, right, top, bottom;
- reader.get_uvlc(&left);
- reader.get_uvlc(&right);
- reader.get_uvlc(&top);
- reader.get_uvlc(&bottom);
+ if (!reader.get_uvlc(&left) ||
+ !reader.get_uvlc(&right) ||
+ !reader.get_uvlc(&top) ||
+ !reader.get_uvlc(&bottom)) {
+ return invalidUVLC;
+ }
//printf("conformance borders: %u %u %u %u\n",left,right,top,bottom);
@@ -310,7 +321,9 @@ Error parse_sps_for_hvcC_configuration2(const uint8_t* sps, size_t size,
*height -= (uint32_t)crop_h;
}
- reader.get_uvlc(&value);
+ if (!reader.get_uvlc(&value)) {
+ return invalidUVLC;
+ }
if (value > 8) {
return Error{heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,
@@ -318,7 +331,9 @@ Error parse_sps_for_hvcC_configuration2(const uint8_t* sps, size_t size,
}
config->bit_depth_luma = (uint8_t) (value + 8);
- reader.get_uvlc(&value);
+ if (!reader.get_uvlc(&value)) {
+ return invalidUVLC;
+ }
if (value > 8) {
return Error{heif_error_Invalid_input,
heif_suberror_Invalid_parameter_value,