Skip to content

Commit 2efb7f3

Browse files
authored
fix divide by zero from crafted file (#99)
see #98
1 parent 1597319 commit 2efb7f3

File tree

4 files changed

+21
-6
lines changed

4 files changed

+21
-6
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
* add `dcm_filehandle_get_frame_number()` [jcupitt]
1111
* add DICOM catenation support [jcupitt]
1212
* fix GCC compiler warning [bgilbert]
13+
- fix /0 from crafted file [xz0x]
1314

1415
## 1.1.0, 28/3/24
1516

src/dicom-data.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,8 @@ bool dcm_element_set_value(DcmError **error,
939939
case DCM_VR_CLASS_NUMERIC_DECIMAL:
940940
case DCM_VR_CLASS_NUMERIC_INTEGER:
941941
size = dcm_dict_vr_size(element->vr);
942-
if (length % size != 0) {
942+
if (size > 0 &&
943+
length % size != 0) {
943944
dcm_error_set(error, DCM_ERROR_CODE_PARSE,
944945
"reading of data element failed",
945946
"bad byte length for numeric type");
@@ -1249,7 +1250,8 @@ char *dcm_element_value_to_string(const DcmElement *element)
12491250
for (i = 0; i < n; i++) {
12501251
result = dcm_printf_append(result, "%02x",
12511252
((unsigned char *) val)[i]);
1252-
if (i % size == size - 1) {
1253+
if (size > 0 &&
1254+
i % size == size - 1) {
12531255
result = dcm_printf_append(result, " ");
12541256
}
12551257
}

src/dicom-file.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,13 @@ static bool get_tiles(DcmError **error,
383383
height = frame_width;
384384
(void) get_tag_int(NULL, metadata, "TotalPixelMatrixRows", &height);
385385

386+
if (width <= 0 || height <= 0) {
387+
dcm_error_set(error, DCM_ERROR_CODE_PARSE,
388+
"frame read failed",
389+
"value of TotalPixelMatrixColumns or TotalPixelMatrixRows is out of range");
390+
return false;
391+
}
392+
386393
*tiles_across = (uint32_t) width / frame_width + !!(width % frame_width);
387394
*tiles_down = (uint32_t) height / frame_height + !!(height % frame_height);
388395

@@ -1643,7 +1650,8 @@ static bool print_pixeldata_create(DcmError **error,
16431650
for (uint32_t i = 0; i < n; i++) {
16441651
printf("%02x", value[i] & 0xff);
16451652

1646-
if (i % size == size - 1) {
1653+
if (size > 0 &&
1654+
i % size == size - 1) {
16471655
printf(" ");
16481656
}
16491657
}

src/dicom-parse.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,9 @@ static bool is_big_endian(void)
154154
static void byteswap(char *data, size_t length, size_t size)
155155
{
156156
// only swap if the data is "swappable"
157-
if (size > 0 && length >= size && length % size == 0) {
157+
if (size > 0 &&
158+
length >= size &&
159+
length % size == 0) {
158160
size_t n_elements = length / size;
159161

160162
switch (size) {
@@ -460,7 +462,8 @@ static bool parse_pixeldata_item(DcmParseState *state,
460462

461463
// native (not encapsulated) pixeldata is always little-endian and needs
462464
// byteswapping on big-endian machines
463-
if (length != 0xffffffff && state->big_endian) {
465+
if (length != 0xffffffff &&
466+
state->big_endian) {
464467
byteswap(value, item_length, dcm_dict_vr_size(vr));
465468
}
466469

@@ -588,7 +591,8 @@ static bool parse_element_body(DcmParseState *state,
588591
if (vr_class == DCM_VR_CLASS_NUMERIC_DECIMAL ||
589592
vr_class == DCM_VR_CLASS_NUMERIC_INTEGER) {
590593
// all numeric classes have a size
591-
if (length % size != 0) {
594+
if (size > 0 &&
595+
length % size != 0) {
592596
dcm_error_set(state->error, DCM_ERROR_CODE_PARSE,
593597
"reading of data element failed",
594598
"bad length for tag '%08x'",

0 commit comments

Comments
 (0)