mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Fix use-after-free when keeping pointers to args from at-files (#1426)
This commit is contained in:
@@ -13,6 +13,7 @@
|
||||
#include <string.h>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "extern/getopt.hpp"
|
||||
#include "file.hpp"
|
||||
@@ -601,7 +602,6 @@ int main(int argc, char *argv[]) {
|
||||
struct AtFileStackEntry {
|
||||
int parentInd; // Saved offset into parent argv
|
||||
std::vector<char *> argv; // This context's arg pointer vec
|
||||
std::vector<char> argPool;
|
||||
|
||||
AtFileStackEntry(int parentInd_, std::vector<char *> argv_)
|
||||
: parentInd(parentInd_), argv(argv_) {}
|
||||
@@ -610,18 +610,24 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
int curArgc = argc;
|
||||
char **curArgv = argv;
|
||||
std::vector<std::vector<char>> argPools;
|
||||
for (;;) {
|
||||
char *atFileName = parseArgv(curArgc, curArgv);
|
||||
if (atFileName) {
|
||||
// We need to allocate a new arg pool for each at-file, so as not to invalidate pointers
|
||||
// previous at-files may have generated to their own arg pools.
|
||||
// But for the same reason, the arg pool must also outlive the at-file's stack entry!
|
||||
auto &argPool = argPools.emplace_back();
|
||||
|
||||
// Copy `argv[0]` for error reporting, and because option parsing skips it
|
||||
AtFileStackEntry &stackEntry =
|
||||
atFileStack.emplace_back(musl_optind, std::vector{atFileName});
|
||||
// It would be nice to compute the char pointers on the fly, but reallocs don't allow
|
||||
// that; so we must compute the offsets after the pool is fixed
|
||||
auto offsets = readAtFile(&musl_optarg[1], stackEntry.argPool);
|
||||
auto offsets = readAtFile(&musl_optarg[1], argPool);
|
||||
stackEntry.argv.reserve(offsets.size() + 2); // Avoid a bunch of reallocs
|
||||
for (size_t ofs : offsets) {
|
||||
stackEntry.argv.push_back(&stackEntry.argPool.data()[ofs]);
|
||||
stackEntry.argv.push_back(&argPool.data()[ofs]);
|
||||
}
|
||||
stackEntry.argv.push_back(nullptr); // Don't forget the arg vector terminator!
|
||||
|
||||
|
||||
14
test/gfx/at-file-ref.err
Normal file
14
test/gfx/at-file-ref.err
Normal file
@@ -0,0 +1,14 @@
|
||||
error: Failed to fit tile colors [$7f55, $7fff] in specified palettes
|
||||
error: Failed to fit tile colors [$7f55] in specified palettes
|
||||
error: Failed to fit tile colors [$6c8a, $7f55, $7fff] in specified palettes
|
||||
error: Failed to fit tile colors [$6c8a, $7fff] in specified palettes
|
||||
error: Failed to fit tile colors [$6c8a, $7f55] in specified palettes
|
||||
error: Failed to fit tile colors [$6c8a] in specified palettes
|
||||
error: Failed to fit tile colors [$7fff] in specified palettes
|
||||
note: The following palettes were specified:
|
||||
[$3f65, $36b3, $262a, $50b0]
|
||||
[$5f77, $213d, $41a6, $40ee]
|
||||
[$5f77, $267c, $213d, $40ee]
|
||||
[$53c3, $3f65, $36b3]
|
||||
[$267c, $41a6]
|
||||
Conversion aborted after 7 errors
|
||||
2
test/gfx/at-file-ref.flags
Normal file
2
test/gfx/at-file-ref.flags
Normal file
@@ -0,0 +1,2 @@
|
||||
-m
|
||||
-c gbc:result.pal
|
||||
BIN
test/gfx/at-file-ref.png
Normal file
BIN
test/gfx/at-file-ref.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 712 B |
Reference in New Issue
Block a user