AP_Filesystem: guarantee load_file() data is null-terminated

Improves safety of use and clarity of users. Termination is not
included in the reported size to avoid changing user behavior or
misrepresenting the file contents.
This commit is contained in:
Thomas Watson 2024-02-23 16:09:37 -06:00 committed by Andrew Tridgell
parent a5764b7413
commit 0ca37387be
5 changed files with 19 additions and 8 deletions

View File

@ -306,7 +306,9 @@ void AP_Filesystem::unmount(void)
} }
/* /*
load a file to memory as a single chunk. Use only for small files Load a file's contents into memory. Returned object must be `delete`d to free
the data. The data is guaranteed to be null-terminated such that it can be
treated as a string.
*/ */
FileData *AP_Filesystem::load_file(const char *filename) FileData *AP_Filesystem::load_file(const char *filename)
{ {

View File

@ -132,7 +132,9 @@ public:
AP_Filesystem_Backend::FormatStatus get_format_status() const; AP_Filesystem_Backend::FormatStatus get_format_status() const;
/* /*
load a full file. Use delete to free the data Load a file's contents into memory. Returned object must be `delete`d to
free the data. The data is guaranteed to be null-terminated such that it
can be treated as a string.
*/ */
FileData *load_file(const char *filename); FileData *load_file(const char *filename);

View File

@ -239,8 +239,9 @@ bool AP_Filesystem_ROMFS::set_mtime(const char *filename, const uint32_t mtime_s
} }
/* /*
load a full file. Use delete to free the data Load a file's contents into memory. Returned object must be `delete`d to free
we override this in ROMFS to avoid taking twice the memory the data. The data is guaranteed to be null-terminated such that it can be
treated as a string. Overridden in ROMFS to avoid taking twice the memory.
*/ */
FileData *AP_Filesystem_ROMFS::load_file(const char *filename) FileData *AP_Filesystem_ROMFS::load_file(const char *filename)
{ {
@ -248,6 +249,7 @@ FileData *AP_Filesystem_ROMFS::load_file(const char *filename)
if (!fd) { if (!fd) {
return nullptr; return nullptr;
} }
// AP_ROMFS adds the guaranteed termination so we don't have to.
fd->data = AP_ROMFS::find_decompress(filename, fd->length); fd->data = AP_ROMFS::find_decompress(filename, fd->length);
if (fd->data == nullptr) { if (fd->data == nullptr) {
delete fd; delete fd;

View File

@ -19,7 +19,9 @@
extern const AP_HAL::HAL& hal; extern const AP_HAL::HAL& hal;
/* /*
load a full file. Use delete to free the data Load a file's contents into memory. Returned object must be `delete`d to free
the data. The data is guaranteed to be null-terminated such that it can be
treated as a string.
*/ */
FileData *AP_Filesystem_Backend::load_file(const char *filename) FileData *AP_Filesystem_Backend::load_file(const char *filename)
{ {
@ -31,7 +33,8 @@ FileData *AP_Filesystem_Backend::load_file(const char *filename)
if (fd == nullptr) { if (fd == nullptr) {
return nullptr; return nullptr;
} }
void *data = malloc(st.st_size); // add one byte for null termination; ArduPilot's malloc will zero it.
void *data = malloc(st.st_size+1);
if (data == nullptr) { if (data == nullptr) {
delete fd; delete fd;
return nullptr; return nullptr;
@ -49,7 +52,7 @@ FileData *AP_Filesystem_Backend::load_file(const char *filename)
return nullptr; return nullptr;
} }
close(d); close(d);
fd->length = st.st_size; fd->length = st.st_size; // length does not include our added termination
fd->data = (const uint8_t *)data; fd->data = (const uint8_t *)data;
return fd; return fd;
} }

View File

@ -87,7 +87,9 @@ public:
virtual AP_Filesystem_Backend::FormatStatus get_format_status() const { return FormatStatus::NOT_STARTED; } virtual AP_Filesystem_Backend::FormatStatus get_format_status() const { return FormatStatus::NOT_STARTED; }
/* /*
load a full file. Use delete to free the data Load a file's contents into memory. Returned object must be `delete`d to
free the data. The data is guaranteed to be null-terminated such that it
can be treated as a string.
*/ */
virtual FileData *load_file(const char *filename); virtual FileData *load_file(const char *filename);