• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bblanchon / ArduinoJson / 22582229047

02 Mar 2026 03:13PM UTC coverage: 99.241% (-0.05%) from 99.289%
22582229047

push

github

bblanchon
Fix buffer overrun in `make_float()`

Fixes #2220

3 of 3 new or added lines in 1 file covered. (100.0%)

4 existing lines in 1 file now uncovered.

4051 of 4082 relevant lines covered (99.24%)

10723.56 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

91.84
/src/ArduinoJson/Numbers/FloatTraits.hpp
1
// ArduinoJson - https://arduinojson.org
2
// Copyright © 2014-2026, Benoit BLANCHON
3
// MIT License
4

5
#pragma once
6

7
#include <stddef.h>  // for size_t
8
#include <stdint.h>
9

10
#include <ArduinoJson/Configuration.hpp>
11
#include <ArduinoJson/Polyfills/alias_cast.hpp>
12
#include <ArduinoJson/Polyfills/math.hpp>
13
#include <ArduinoJson/Polyfills/pgmspace_generic.hpp>
14
#include <ArduinoJson/Polyfills/preprocessor.hpp>
15
#include <ArduinoJson/Polyfills/type_traits.hpp>
16

17
ARDUINOJSON_BEGIN_PRIVATE_NAMESPACE
18

19
template <typename T, size_t = sizeof(T)>
20
struct FloatTraits {};
21

22
template <typename T>
23
struct FloatTraits<T, 8 /*64bits*/> {
24
  using mantissa_type = uint64_t;
25
  static const short mantissa_bits = 52;
26
  static const mantissa_type mantissa_max =
27
      (mantissa_type(1) << mantissa_bits) - 1;
28

29
  using exponent_type = int16_t;
30
  static const exponent_type exponent_max = 308;
31

32
  static const size_t binaryPowersOfTen = 9;
33

34
  static pgm_ptr<T> positiveBinaryPowersOfTen() {
119✔
UNCOV
35
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
×
36
        uint64_t, factors,
37
        {
38
            0x4024000000000000,  // 1e1
39
            0x4059000000000000,  // 1e2
40
            0x40C3880000000000,  // 1e4
41
            0x4197D78400000000,  // 1e8
42
            0x4341C37937E08000,  // 1e16
43
            0x4693B8B5B5056E17,  // 1e32
44
            0x4D384F03E93FF9F5,  // 1e64
45
            0x5A827748F9301D32,  // 1e128
46
            0x75154FDD7F73BF3C,  // 1e256
47
        });
48
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
119✔
49
  }
50

51
  static pgm_ptr<T> negativeBinaryPowersOfTen() {
117✔
UNCOV
52
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(  //
×
53
        uint64_t, factors,
54
        {
55
            0x3FB999999999999A,  // 1e-1
56
            0x3F847AE147AE147B,  // 1e-2
57
            0x3F1A36E2EB1C432D,  // 1e-4
58
            0x3E45798EE2308C3A,  // 1e-8
59
            0x3C9CD2B297D889BC,  // 1e-16
60
            0x3949F623D5A8A733,  // 1e-32
61
            0x32A50FFD44F4A73D,  // 1e-64
62
            0x255BBA08CF8C979D,  // 1e-128
63
            0x0AC8062864AC6F43   // 1e-256
64
        });
65
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
117✔
66
  }
67

68
  static T nan() {
8✔
69
    return forge(0x7ff8000000000000);
8✔
70
  }
71

72
  static T inf() {
15✔
73
    return forge(0x7ff0000000000000);
15✔
74
  }
75

76
  static T highest() {
77
    return forge(0x7FEFFFFFFFFFFFFF);
78
  }
79

80
  template <typename TOut>  // int64_t
81
  static T highest_for(
5✔
82
      enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
83
                      sizeof(TOut) == 8,
84
                  signed>* = 0) {
85
    return forge(0x43DFFFFFFFFFFFFF);  //  9.2233720368547748e+18
5✔
86
  }
87

88
  template <typename TOut>  // uint64_t
89
  static T highest_for(
3✔
90
      enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
91
                      sizeof(TOut) == 8,
92
                  unsigned>* = 0) {
93
    return forge(0x43EFFFFFFFFFFFFF);  //  1.8446744073709549568e+19
3✔
94
  }
95

96
  static T lowest() {
97
    return forge(0xFFEFFFFFFFFFFFFF);
98
  }
99

100
  // constructs a double floating point values from its binary representation
101
  // we use this function to workaround platforms with single precision literals
102
  // (for example, when -fsingle-precision-constant is passed to GCC)
103
  static T forge(uint64_t bits) {
31✔
104
    return alias_cast<T>(bits);
31✔
105
  }
106
};
107

108
template <typename T>
109
struct FloatTraits<T, 4 /*32bits*/> {
110
  using mantissa_type = uint32_t;
111
  static const short mantissa_bits = 23;
112
  static const mantissa_type mantissa_max =
113
      (mantissa_type(1) << mantissa_bits) - 1;
114

115
  using exponent_type = int8_t;
116
  static const exponent_type exponent_max = 38;
117

118
  static const size_t binaryPowersOfTen = 6;
119

120
  static pgm_ptr<T> positiveBinaryPowersOfTen() {
19✔
121
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
1✔
122
                                     {
123
                                         0x41200000,  // 1e1f
124
                                         0x42c80000,  // 1e2f
125
                                         0x461c4000,  // 1e4f
126
                                         0x4cbebc20,  // 1e8f
127
                                         0x5a0e1bca,  // 1e16f
128
                                         0x749dc5ae   // 1e32f
129
                                     });
130
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
19✔
131
  }
132

133
  static pgm_ptr<T> negativeBinaryPowersOfTen() {
85✔
134
    ARDUINOJSON_DEFINE_PROGMEM_ARRAY(uint32_t, factors,
1✔
135
                                     {
136
                                         0x3dcccccd,  // 1e-1f
137
                                         0x3c23d70a,  // 1e-2f
138
                                         0x38d1b717,  // 1e-4f
139
                                         0x322bcc77,  // 1e-8f
140
                                         0x24e69595,  // 1e-16f
141
                                         0x0a4fb11f   // 1e-32f
142
                                     });
143
    return pgm_ptr<T>(reinterpret_cast<const T*>(factors));
85✔
144
  }
145

146
  static T forge(uint32_t bits) {
40✔
147
    return alias_cast<T>(bits);
40✔
148
  }
149

UNCOV
150
  static T nan() {
×
UNCOV
151
    return forge(0x7fc00000);
×
152
  }
153

154
  static T inf() {
2✔
155
    return forge(0x7f800000);
2✔
156
  }
157

158
  static T highest() {
159
    return forge(0x7f7fffff);
160
  }
161

162
  template <typename TOut>  // int32_t
163
  static T highest_for(
5✔
164
      enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
165
                      sizeof(TOut) == 4,
166
                  signed>* = 0) {
167
    return forge(0x4EFFFFFF);  // 2.14748352E9
5✔
168
  }
169

170
  template <typename TOut>  // uint32_t
171
  static T highest_for(
4✔
172
      enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
173
                      sizeof(TOut) == 4,
174
                  unsigned>* = 0) {
175
    return forge(0x4F7FFFFF);  // 4.29496704E9
4✔
176
  }
177

178
  template <typename TOut>  // int64_t
179
  static T highest_for(
26✔
180
      enable_if_t<is_integral<TOut>::value && is_signed<TOut>::value &&
181
                      sizeof(TOut) == 8,
182
                  signed>* = 0) {
183
    return forge(0x5EFFFFFF);  // 9.22337148709896192E18
26✔
184
  }
185

186
  template <typename TOut>  // uint64_t
187
  static T highest_for(
3✔
188
      enable_if_t<is_integral<TOut>::value && is_unsigned<TOut>::value &&
189
                      sizeof(TOut) == 8,
190
                  unsigned>* = 0) {
191
    return forge(0x5F7FFFFF);  // 1.844674297419792384E19
3✔
192
  }
193

194
  static T lowest() {
195
    return forge(0xFf7fffff);
196
  }
197
};
198

199
template <typename TFloat, typename TExponent>
200
inline TFloat make_float(TFloat m, TExponent e) {
137✔
201
  using traits = FloatTraits<TFloat>;
202

203
  auto powersOfTen = e > 0 ? traits::positiveBinaryPowersOfTen()
137✔
204
                           : traits::negativeBinaryPowersOfTen();
99✔
205
  auto count = traits::binaryPowersOfTen;
137✔
206

207
  if (e <= 0)
137✔
208
    e = TExponent(-e);
99✔
209

210
  for (uint8_t index = 0; e != 0; index++) {
638✔
211
    if (index >= count)
503✔
212
      return traits::nan();
2✔
213
    if (e & 1)
501✔
214
      m *= powersOfTen[index];
228✔
215
    e >>= 1;
501✔
216
  }
217
  return m;
135✔
218
}
219

220
ARDUINOJSON_END_PRIVATE_NAMESPACE
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc