|
6 | 6 | * INCLUDE
|
7 | 7 | **************************************************************************************/
|
8 | 8 |
|
9 |
| -#include <api/deprecated-avr-comp/avr/dtostrf.h> |
10 |
| - |
11 |
| -#include <stdlib.h> |
| 9 | +#include <cstdio> |
| 10 | +#include <cfloat> |
12 | 11 |
|
13 | 12 | /**************************************************************************************
|
14 | 13 | * FUNCTION IMPLEMENTATION
|
|
17 | 16 | #ifdef __cplusplus
|
18 | 17 | extern "C" {
|
19 | 18 | #endif
|
| 19 | +/* |
| 20 | + * A fundamental issue with dtostrf is the risk of buffer overflow as the size of the |
| 21 | + * output buffer is not passed in. Previous implementation relied on sprintf which has |
| 22 | + * the same issue and has now been deprecated, leading to compilation warnings that are |
| 23 | + * considered fatal. Here, we use snprintf to avoid those warnings, with a limit |
| 24 | + * set large enough for the longest buffer used by the String class. The risk |
| 25 | + * of buffer overflow remains when a smaller buffer is passed in. |
| 26 | + * |
| 27 | + * TODO Refactor String not to rely on this function. |
| 28 | + */ |
| 29 | +char *dtostrf (double val, signed char width, unsigned char prec, char *sout) { |
| 30 | + |
| 31 | + // From String.h - DOUBLE_BUF_SIZE is the largest it could use |
| 32 | + static size_t const FLT_MAX_DECIMAL_PLACES = 10; |
| 33 | + static size_t const DBL_MAX_DECIMAL_PLACES = FLT_MAX_DECIMAL_PLACES; |
| 34 | + static size_t const DOUBLE_BUF_SIZE = DBL_MAX_10_EXP + DBL_MAX_DECIMAL_PLACES + 1 /* '-' */ + 1 /* '.' */ + 1 /* '\0' */; |
20 | 35 |
|
21 |
| -#include <api/deprecated-avr-comp/avr/dtostrf.c.impl> |
| 36 | + char fmt[20]; |
| 37 | + snprintf(fmt, sizeof(fmt), "%%%d.%df", width, prec); |
| 38 | + snprintf(sout, DOUBLE_BUF_SIZE, fmt, val); |
| 39 | + return sout; |
| 40 | +} |
22 | 41 |
|
23 | 42 | #ifdef __cplusplus
|
24 | 43 | } // extern "C"
|
|
0 commit comments