FastLED 3.10.8
Loading...
Searching...
No Matches
string_holder.cpp.hpp
Go to the documentation of this file.
1// IWYU pragma: begin_keep
2#include <stdlib.h>
3#include <string.h> // okay banned header (STL wrapper implementation requires standard header for strlen)
4
5// IWYU pragma: end_keep
7#include "fl/stl/cstring.h" // For memcpy
8#include "fl/stl/malloc.h" // For fl::malloc, fl::free, fl::realloc
9#include "fl/stl/noexcept.h"
10
11namespace fl {
12
13// StringHolder implementations
14//
15// OOM hardening (FastLED#3588): on classic ESP32 with WiFi + an HTTP
16// server active, free heap drops below 20 KB and fl::malloc genuinely
17// returns NULL. The previous "OOM is terminal" assumption turned that
18// into UB (writes through null; realloc leak plus null mData with a
19// stale nonzero capacity) and crashed unattended bench devices. On
20// failure a holder now degrades to a coherent empty state
21// (mData=null, mLength=0, mCapacity=0) and grow() keeps the old
22// buffer.
23
25 : mData((char*)fl::malloc(strlen(str) + 1))
26 , mLength(strlen(str))
27 , mCapacity(mLength + 1) {
28 if (mData == nullptr) {
29 mLength = 0;
30 mCapacity = 0;
31 return;
32 }
34 mData[mLength] = '\0';
35}
36
38 : mData((char*)fl::malloc(length + 1))
40 , mCapacity(length + 1) {
41 if (mData == nullptr) {
42 mLength = 0;
43 mCapacity = 0;
44 return;
45 }
46 mData[mLength] = '\0';
47}
48
50 : mData((char*)fl::malloc(length + 1))
52 , mCapacity(length + 1) {
53 if (mData == nullptr) {
54 mLength = 0;
55 mCapacity = 0;
56 return;
57 }
59 mData[mLength] = '\0';
60}
61
65
66void StringHolder::grow(size newLength) FL_NO_EXCEPT {
67 if (newLength + 1 <= mCapacity) {
68 // We have enough capacity for newLength + null terminator
69 mLength = newLength;
70 mData[mLength] = '\0';
71 return;
72 }
73
74 // Use fl::realloc for efficient growth without memory move.
75 // Keep the old buffer if the allocation fails — the string simply
76 // does not grow (callers observe the unchanged length).
77 char *grown = (char*)fl::realloc(mData, newLength + 1);
78 if (grown == nullptr) {
79 return;
80 }
81 mData = grown;
82 mLength = newLength;
83 mCapacity = newLength + 1;
84 mData[mLength] = '\0'; // Ensure null-termination
85}
86
87} // namespace fl
void grow(size newLength) FL_NO_EXCEPT
~StringHolder() FL_DTOR_NOEXCEPT
size length() const FL_NO_EXCEPT
StringHolder(const char *str) FL_NO_EXCEPT
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
FASTLED_FORCE_INLINE void free(void *ptr) FL_NO_EXCEPT
Definition malloc.h:23
FASTLED_FORCE_INLINE void * malloc(size_t size) FL_NO_EXCEPT
Definition malloc.h:21
FASTLED_FORCE_INLINE void * memcpy(void *dest, const void *src, size_t n) FL_NO_EXCEPT
Definition cstring.h:136
FASTLED_FORCE_INLINE void * realloc(void *ptr, size_t new_size) FL_NO_EXCEPT
Definition malloc.h:27
FASTLED_FORCE_INLINE size_t strlen(const char *s) FL_NO_EXCEPT
Definition cstring.h:56
Base definition for an LED controller.
Definition crgb.hpp:179
#define FL_DTOR_NOEXCEPT