|
6 | 6 | #include "formatstyle.hxx" |
7 | 7 | #include "logrecord.hxx" |
8 | 8 |
|
9 | | -constexpr const size_t MAX_FORMATED_ASCTIME_SIZE = 64; |
10 | | -constexpr const size_t MAX_DATEFMT_WITH_MICROSECONDS_SIZE = 64; |
| 9 | +// Size of the temporary buffer on stack to format asctime. |
| 10 | +// 64 - is big enough. |
| 11 | +// For example: "2024-07-23 03:27:04.982856" - is just 29 bytes |
| 12 | +constexpr const size_t MAX_FORMATTED_ASCTIME_SIZE = 64; |
11 | 13 |
|
12 | 14 | PyObject* Formatter_new(PyTypeObject* type, PyObject* args, PyObject* kwds) |
13 | 15 | { |
@@ -77,10 +79,11 @@ int Formatter_init(Formatter *self, PyObject *args, PyObject *kwds){ |
77 | 79 | std::string_view dateFmtSV = self->dateFmtStr; |
78 | 80 | self->dateFmtStrSize = dateFmtSV.size(); |
79 | 81 |
|
80 | | - // We use temporary buffer on stack later to format %f before using standard strftime |
81 | | - // This protects against buffer overflow |
82 | | - // Breaching this will simply disable formatting of %f |
83 | | - if (self->dateFmtStrSize < MAX_DATEFMT_WITH_MICROSECONDS_SIZE - 8) |
| 82 | + // Later we use temporary buffer allocated on stack to format %f before using standard strftime |
| 83 | + // This check protects against buffer overflow. If dateFmt is too large for the buffer |
| 84 | + // (bigger than in this check) then %f formatting will be disabled thus dateFmt will be passed |
| 85 | + // directly to strftime |
| 86 | + if (self->dateFmtStrSize <= MAX_FORMATTED_ASCTIME_SIZE - 4) |
84 | 87 | self->dateFmtMicrosendsPos = dateFmtSV.find("%f"); |
85 | 88 | } else { |
86 | 89 | self->dateFmtStr = nullptr; |
@@ -110,15 +113,13 @@ PyObject* Formatter_format(Formatter *self, PyObject *record){ |
110 | 113 | std::time_t created = static_cast<std::time_t>(createdInt); |
111 | 114 | std::tm *ct = localtime(&created); |
112 | 115 |
|
113 | | - // 64 - is big enough to fit any formatted asctime |
114 | | - // For example: "2024-07-23 03:27:04.982856" - is just 29 bytes |
115 | | - char buf[MAX_FORMATED_ASCTIME_SIZE]; |
| 116 | + char buf[MAX_FORMATTED_ASCTIME_SIZE + 1]; |
116 | 117 |
|
117 | 118 | if (self->dateFmt != Py_None){ |
118 | 119 | size_t len; |
119 | 120 |
|
120 | 121 | if (self->dateFmtMicrosendsPos != std::string_view::npos){ |
121 | | - char formatStrBuf[MAX_DATEFMT_WITH_MICROSECONDS_SIZE]; |
| 122 | + char formatStrBuf[MAX_FORMATTED_ASCTIME_SIZE + 1]; |
122 | 123 | // Copy everything before %f |
123 | 124 | memcpy(formatStrBuf, self->dateFmtStr, self->dateFmtMicrosendsPos); |
124 | 125 | // Format microseconds |
|
0 commit comments