Skip to content

Commit

Permalink
Make JPEGLI_ERROR truly no-return (#3330)
Browse files Browse the repository at this point in the history
  • Loading branch information
eustas committed Feb 26, 2024
1 parent 7a38ce9 commit 0f0997c
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 32 deletions.
6 changes: 3 additions & 3 deletions lib/jpegli/decode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ void BuildHuffmanLookupTable(j_decompress_ptr cinfo, JHUFF_TBL* table,
for (int i = 0; i < total_count; ++i) {
int value = table->huffval[i];
if (values_seen[value]) {
return JPEGLI_ERROR("Duplicate Huffman code value %d", value);
JPEGLI_ERROR("Duplicate Huffman code value %d", value);
}
values_seen[value] = 1;
values[i] = value;
Expand Down Expand Up @@ -223,7 +223,7 @@ void PrepareForScan(j_decompress_ptr cinfo) {
HuffmanTableEntry* huff_lut =
&m->dc_huff_lut_[dc_tbl_idx * kJpegHuffmanLutSize];
if (!table) {
return JPEGLI_ERROR("DC Huffman table %d not found", dc_tbl_idx);
JPEGLI_ERROR("DC Huffman table %d not found", dc_tbl_idx);
}
BuildHuffmanLookupTable(cinfo, table, huff_lut);
}
Expand All @@ -233,7 +233,7 @@ void PrepareForScan(j_decompress_ptr cinfo) {
HuffmanTableEntry* huff_lut =
&m->ac_huff_lut_[ac_tbl_idx * kJpegHuffmanLutSize];
if (!table) {
return JPEGLI_ERROR("AC Huffman table %d not found", ac_tbl_idx);
JPEGLI_ERROR("AC Huffman table %d not found", ac_tbl_idx);
}
BuildHuffmanLookupTable(cinfo, table, huff_lut);
}
Expand Down
52 changes: 25 additions & 27 deletions lib/jpegli/decode_marker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,22 @@ constexpr uint8_t kIccProfileTag[12] = "ICC_PROFILE";

// Macros for commonly used error conditions.

#define JPEG_VERIFY_LEN(n) \
if (pos + (n) > len) { \
return JPEGLI_ERROR("Unexpected end of marker: pos=%" PRIuS \
" need=%d len=%" PRIuS, \
pos, static_cast<int>(n), len); \
#define JPEG_VERIFY_LEN(n) \
if (pos + (n) > len) { \
JPEGLI_ERROR("Unexpected end of marker: pos=%" PRIuS \
" need=%d len=%" PRIuS, \
pos, static_cast<int>(n), len); \
}

#define JPEG_VERIFY_INPUT(var, low, high) \
if ((var) < (low) || (var) > (high)) { \
return JPEGLI_ERROR("Invalid " #var ": %d", static_cast<int>(var)); \
#define JPEG_VERIFY_INPUT(var, low, high) \
if ((var) < (low) || (var) > (high)) { \
JPEGLI_ERROR("Invalid " #var ": %d", static_cast<int>(var)); \
}

#define JPEG_VERIFY_MARKER_END() \
if (pos != len) { \
return JPEGLI_ERROR("Invalid marker length: declared=%" PRIuS \
" actual=%" PRIuS, \
len, pos); \
#define JPEG_VERIFY_MARKER_END() \
if (pos != len) { \
JPEGLI_ERROR("Invalid marker length: declared=%" PRIuS " actual=%" PRIuS, \
len, pos); \
}

inline int ReadUint8(const uint8_t* data, size_t* pos) {
Expand Down Expand Up @@ -181,7 +180,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
for (int i = 0; i < cinfo->comps_in_scan; ++i) {
int id = ReadUint8(data, &pos);
if (ids_seen[id]) { // (cf. section B.2.3, regarding CSj)
return JPEGLI_ERROR("Duplicate ID %d in SOS.", id);
JPEGLI_ERROR("Duplicate ID %d in SOS.", id);
}
ids_seen[id] = 1;
jpeg_component_info* comp = nullptr;
Expand All @@ -192,8 +191,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
}
}
if (!comp) {
return JPEGLI_ERROR("SOS marker: Could not find component with id %d",
id);
JPEGLI_ERROR("SOS marker: Could not find component with id %d", id);
}
int c = ReadUint8(data, &pos);
comp->dc_tbl_no = c >> 4;
Expand Down Expand Up @@ -261,12 +259,12 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
int comp_idx = cinfo->cur_comp_info[i]->component_index;
for (int k = cinfo->Ss; k <= cinfo->Se; ++k) {
if (m->scan_progression_[comp_idx][k] & scan_bitmask) {
return JPEGLI_ERROR(
JPEGLI_ERROR(
"Overlapping scans: component=%d k=%d prev_mask: %u cur_mask %u",
comp_idx, k, m->scan_progression_[i][k], scan_bitmask);
}
if (m->scan_progression_[comp_idx][k] & refinement_bitmask) {
return JPEGLI_ERROR(
JPEGLI_ERROR(
"Invalid scan order, a more refined scan was already done: "
"component=%d k=%d prev_mask=%u cur_mask=%u",
comp_idx, k, m->scan_progression_[i][k], scan_bitmask);
Expand All @@ -275,7 +273,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
}
}
if (cinfo->Al > 10) {
return JPEGLI_ERROR("Scan parameter Al=%d is not supported.", cinfo->Al);
JPEGLI_ERROR("Scan parameter Al=%d is not supported.", cinfo->Al);
}
}

Expand All @@ -285,7 +283,7 @@ void ProcessSOS(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
void ProcessDHT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
size_t pos = 2;
if (pos == len) {
return JPEGLI_ERROR("DHT marker: no Huffman table found");
JPEGLI_ERROR("DHT marker: no Huffman table found");
}
while (pos < len) {
JPEG_VERIFY_LEN(1 + kJpegHuffmanMaxBitLength);
Expand Down Expand Up @@ -343,7 +341,7 @@ void ProcessDQT(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
}
size_t pos = 2;
if (pos == len) {
return JPEGLI_ERROR("DQT marker: no quantization table found");
JPEGLI_ERROR("DQT marker: no quantization table found");
}
while (pos < len) {
JPEG_VERIFY_LEN(1);
Expand Down Expand Up @@ -377,7 +375,7 @@ void ProcessDNL(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
void ProcessDRI(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
jpeg_decomp_master* m = cinfo->master;
if (m->found_dri_) {
return JPEGLI_ERROR("Duplicate DRI marker.");
JPEGLI_ERROR("Duplicate DRI marker.");
}
m->found_dri_ = true;
size_t pos = 2;
Expand Down Expand Up @@ -411,24 +409,24 @@ void ProcessAPP(j_decompress_ptr cinfo, const uint8_t* data, size_t len) {
payload += sizeof(kIccProfileTag);
payload_size -= sizeof(kIccProfileTag);
if (payload_size < 2) {
return JPEGLI_ERROR("ICC chunk is too small.");
JPEGLI_ERROR("ICC chunk is too small.");
}
uint8_t index = payload[0];
uint8_t total = payload[1];
++m->icc_index_;
if (m->icc_index_ != index) {
return JPEGLI_ERROR("Invalid ICC chunk order.");
JPEGLI_ERROR("Invalid ICC chunk order.");
}
if (total == 0) {
return JPEGLI_ERROR("Invalid ICC chunk total.");
JPEGLI_ERROR("Invalid ICC chunk total.");
}
if (m->icc_total_ == 0) {
m->icc_total_ = total;
} else if (m->icc_total_ != total) {
return JPEGLI_ERROR("Invalid ICC chunk total.");
JPEGLI_ERROR("Invalid ICC chunk total.");
}
if (m->icc_index_ > m->icc_total_) {
return JPEGLI_ERROR("Invalid ICC chunk index.");
JPEGLI_ERROR("Invalid ICC chunk index.");
}
m->icc_profile_.insert(m->icc_profile_.end(), payload + 2,
payload + payload_size);
Expand Down
2 changes: 1 addition & 1 deletion lib/jpegli/encode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ void jpegli_copy_critical_parameters(j_decompress_ptr srcinfo,
jpegli_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
if (dstinfo->num_components != srcinfo->num_components) {
const auto& cinfo = dstinfo;
return JPEGLI_ERROR("Mismatch between src colorspace and components");
JPEGLI_ERROR("Mismatch between src colorspace and components");
}
dstinfo->data_precision = srcinfo->data_precision;
dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
Expand Down
5 changes: 4 additions & 1 deletion lib/jpegli/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,20 @@
#include <stdint.h>

#include "lib/jpegli/common.h"
#include "lib/jxl/base/status.h"

namespace jpegli {

bool FormatString(char* buffer, const char* format, ...);

} // namespace jpegli

// `error_exit` should be no-return; but let's add some guarantees on our side.
#define JPEGLI_ERROR(format, ...) \
jpegli::FormatString(cinfo->err->msg_parm.s, ("%s:%d: " format), __FILE__, \
__LINE__, ##__VA_ARGS__), \
(*cinfo->err->error_exit)(reinterpret_cast<j_common_ptr>(cinfo))
(*cinfo->err->error_exit)(reinterpret_cast<j_common_ptr>(cinfo)), \
(void)jxl::Abort()

#define JPEGLI_WARN(format, ...) \
jpegli::FormatString(cinfo->err->msg_parm.s, ("%s:%d: " format), __FILE__, \
Expand Down

0 comments on commit 0f0997c

Please sign in to comment.