Coverage Report

Created: 2026-03-31 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/dcmtk-fuzzers/dcmtk_dicom_fuzzer.cc
Line
Count
Source
1
// Copyright 2026 Google LLC
2
//
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
6
//
7
//      http://www.apache.org/licenses/LICENSE-2.0
8
//
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
// See the License for the specific language governing permissions and
13
// limitations under the License.
14
//
15
///////////////////////////////////////////////////////////////////////////
16
#include <cstdint>
17
#include <cstddef>
18
#include <cstdlib>
19
#include <new>
20
#include <string>
21
22
#include "dcmtk/dcmdata/dctk.h"
23
#include "dcmtk/dcmdata/dcistrmb.h"
24
#include "dcmtk/dcmdata/dcdeftag.h"
25
#include "dcmtk/dcmdata/dcxfer.h"
26
27
static constexpr std::size_t kNewNothrowCap = 8 * 1024 * 1024;
28
29
0
void* operator new(std::size_t n, const std::nothrow_t&) noexcept {
30
0
  if (n > kNewNothrowCap) return nullptr;
31
0
  try { return ::operator new(n); } catch (...) { return nullptr; }
32
0
}
33
0
void* operator new[](std::size_t n, const std::nothrow_t&) noexcept {
34
0
  if (n > kNewNothrowCap) return nullptr;
35
0
  try { return ::operator new[](n); } catch (...) { return nullptr; }
36
0
}
37
38
0
static void walkDataset(DcmItem* item) {
39
0
  if (!item) return;
40
0
  DcmStack stack;
41
0
  if (item->nextObject(stack, OFTrue).good()) {
42
0
    do {
43
0
      DcmObject* obj = stack.top();
44
0
      if (!obj) break;
45
0
      (void)obj->ident();
46
0
      (void)obj->getTag();
47
0
    } while (item->nextObject(stack, OFFalse).good());
48
0
  }
49
0
}
50
51
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
52
  static bool dict_set = (setenv("DCMDICTPATH", "/out/dicom.dic", 0), true);
53
  (void)dict_set;
54
55
  DcmInputBufferStream in;
56
  in.setBuffer((void*)data, size);
57
  in.setEos();
58
59
  DcmFileFormat file;
60
  const Uint32 kMaxReadLen = 256 * 1024;
61
62
  if (file.read(in, EXS_Unknown, EGL_noChange, kMaxReadLen).good()) {
63
    if (auto* ds = file.getDataset()) {
64
      (void)ds->chooseRepresentation(EXS_LittleEndianExplicit, nullptr);
65
      (void)ds->calcElementLength(EXS_LittleEndianExplicit, EET_ExplicitLength);
66
67
      OFString s;
68
      (void)ds->findAndGetOFString(DCM_PatientName, s);
69
      (void)ds->findAndGetOFString(DCM_StudyInstanceUID, s);
70
      (void)ds->findAndGetOFString(DCM_SOPClassUID, s);
71
72
      walkDataset(ds);
73
    }
74
  }
75
  return 0;
76
}