Coverage Report

Created: 2026-05-24 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libheif/libheif/security_limits.h
Line
Count
Source
1
/*
2
 * HEIF codec.
3
 * Copyright (c) 2018 Dirk Farin <dirk.farin@gmail.com>
4
 *
5
 * This file is part of libheif.
6
 *
7
 * libheif is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Lesser General Public License as
9
 * published by the Free Software Foundation, either version 3 of
10
 * the License, or (at your option) any later version.
11
 *
12
 * libheif is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU Lesser General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Lesser General Public License
18
 * along with libheif.  If not, see <http://www.gnu.org/licenses/>.
19
 */
20
#ifndef LIBHEIF_SECURITY_LIMITS_H
21
#define LIBHEIF_SECURITY_LIMITS_H
22
23
#include "libheif/heif.h"
24
#include <cinttypes>
25
#include <cstddef>
26
#include "error.h"
27
28
29
extern heif_security_limits global_security_limits;
30
extern heif_security_limits disabled_security_limits;
31
32
// Maximum nesting level of boxes in input files.
33
// We put a limit on this to avoid unlimited stack usage by malicious input files.
34
static const int MAX_BOX_NESTING_LEVEL = 20;
35
36
static const int MAX_BOX_SIZE = 0x7FFFFFFF; // 2 GB
37
static const int64_t MAX_LARGE_BOX_SIZE = 0x0FFFFFFFFFFFFFFF;
38
static const int64_t MAX_FILE_POS = 0x007FFFFFFFFFFFFFLL; // maximum file position
39
static const int MAX_FRACTION_VALUE = 0x10000;
40
41
42
Error check_for_valid_image_size(const heif_security_limits* limits, uint32_t width, uint32_t height);
43
44
// Maximum coding-unit size (in pixels) that the given codec may pad a coded
45
// frame up to. Used as the margin for tighten_image_size_limit_for_ispe.
46
// Returns 0 for codecs without coding-unit padding (e.g. uncompressed).
47
uint32_t max_coding_unit_size_for_codec(heif_compression_format format);
48
49
// Return a copy of `base` with max_image_size_pixels lowered to a value
50
// just above the declared image size. This is used to bound how much memory
51
// a codec plugin may allocate for an image whose internal (codec-declared)
52
// dimensions exceed the file-declared (ispe) dimensions — without us having
53
// to parse the codec bitstream ourselves.
54
//
55
// `coding_unit_size` is the maximum coding-unit size of the target codec
56
// (e.g. 128 for AV1/VVC, 64 for HEVC, 16 for AVC). The allowed coded
57
// dimensions are (ispe + coding_unit_size) in each axis, since a codec may
58
// pad the coded frame up to a coding-unit boundary.
59
heif_security_limits tighten_image_size_limit_for_ispe(const heif_security_limits* base,
60
                                                       uint32_t ispe_width,
61
                                                       uint32_t ispe_height,
62
                                                       uint32_t coding_unit_size);
63
64
65
class TotalMemoryTracker
66
{
67
public:
68
  explicit TotalMemoryTracker(const heif_security_limits* limits_context);
69
  ~TotalMemoryTracker();
70
71
  size_t get_max_total_memory_used() const;
72
73
  void operator=(const TotalMemoryTracker&) = delete;
74
  TotalMemoryTracker(const TotalMemoryTracker&) = delete;
75
76
private:
77
  const heif_security_limits* m_limits_context = nullptr;
78
};
79
80
81
class MemoryHandle
82
{
83
public:
84
243k
  MemoryHandle() = default;
85
360k
  ~MemoryHandle() { free(); }
86
87
  Error alloc(size_t memory_amount, const heif_security_limits* limits_context, const char* reason_description);
88
89
  void free();
90
91
  void free(size_t memory_amount);
92
93
41
  const heif_security_limits* get_security_limits() const { return m_limits_context; }
94
95
  MemoryHandle(const MemoryHandle&) = delete;
96
  MemoryHandle& operator=(const MemoryHandle&) = delete;
97
98
  MemoryHandle(MemoryHandle&& other) noexcept
99
117k
      : m_limits_context(other.m_limits_context), m_memory_amount(other.m_memory_amount)
100
117k
  {
101
117k
    other.m_limits_context = nullptr;
102
117k
    other.m_memory_amount = 0;
103
117k
  }
104
105
  MemoryHandle& operator=(MemoryHandle&& other) noexcept
106
117k
  {
107
117k
    if (this != &other) {
108
117k
      free();
109
117k
      m_limits_context = other.m_limits_context;
110
117k
      m_memory_amount = other.m_memory_amount;
111
117k
      other.m_limits_context = nullptr;
112
117k
      other.m_memory_amount = 0;
113
117k
    }
114
117k
    return *this;
115
117k
  }
116
117
private:
118
  const heif_security_limits* m_limits_context = nullptr;
119
  size_t m_memory_amount = 0;
120
};
121
122
123
#endif  // LIBHEIF_SECURITY_LIMITS_H