mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-20 18:22:07 +00:00
Ensure that INCBIN parameters are non-negative
This commit is contained in:
@@ -96,8 +96,8 @@ void sect_RelBytes(uint32_t n, std::vector<Expression> const &exprs);
|
|||||||
void sect_RelWord(Expression const &expr, uint32_t pcShift);
|
void sect_RelWord(Expression const &expr, uint32_t pcShift);
|
||||||
void sect_RelLong(Expression const &expr, uint32_t pcShift);
|
void sect_RelLong(Expression const &expr, uint32_t pcShift);
|
||||||
void sect_PCRelByte(Expression const &expr, uint32_t pcShift);
|
void sect_PCRelByte(Expression const &expr, uint32_t pcShift);
|
||||||
void sect_BinaryFile(std::string const &name, int32_t startPos);
|
void sect_BinaryFile(std::string const &name, uint32_t startPos);
|
||||||
void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t length);
|
void sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length);
|
||||||
|
|
||||||
void sect_EndSection();
|
void sect_EndSection();
|
||||||
void sect_PushSection();
|
void sect_PushSection();
|
||||||
|
|||||||
@@ -1153,13 +1153,13 @@ incbin:
|
|||||||
YYACCEPT;
|
YYACCEPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| POP_INCBIN string COMMA iconst {
|
| POP_INCBIN string COMMA uconst {
|
||||||
sect_BinaryFile($2, $4);
|
sect_BinaryFile($2, $4);
|
||||||
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
||||||
YYACCEPT;
|
YYACCEPT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| POP_INCBIN string COMMA iconst COMMA iconst {
|
| POP_INCBIN string COMMA uconst COMMA uconst {
|
||||||
sect_BinaryFileSlice($2, $4, $6);
|
sect_BinaryFileSlice($2, $4, $6);
|
||||||
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
if (failedOnMissingInclude && !continueAfterMissingIncludes) {
|
||||||
YYACCEPT;
|
YYACCEPT;
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ static Section *currentLoadSection = nullptr;
|
|||||||
static std::pair<Symbol const *, Symbol const *> currentLoadLabelScopes = {nullptr, nullptr};
|
static std::pair<Symbol const *, Symbol const *> currentLoadLabelScopes = {nullptr, nullptr};
|
||||||
int32_t loadOffset; // Offset into the LOAD section's parent (see sect_GetOutputOffset)
|
int32_t loadOffset; // Offset into the LOAD section's parent (see sect_GetOutputOffset)
|
||||||
|
|
||||||
// A quick check to see if we have an initialized section
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
static bool requireSection() {
|
static bool requireSection() {
|
||||||
if (currentSection) {
|
if (currentSection) {
|
||||||
@@ -61,8 +60,6 @@ static bool requireSection() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// A quick check to see if we have an initialized section that can contain
|
|
||||||
// this much initialized data
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
static bool requireCodeSection() {
|
static bool requireCodeSection() {
|
||||||
if (!requireSection()) {
|
if (!requireSection()) {
|
||||||
@@ -278,7 +275,6 @@ static void mergeSections(
|
|||||||
|
|
||||||
#undef sectError
|
#undef sectError
|
||||||
|
|
||||||
// Create a new section, not yet in the list.
|
|
||||||
static Section *createSection(
|
static Section *createSection(
|
||||||
std::string const &name,
|
std::string const &name,
|
||||||
SectionType type,
|
SectionType type,
|
||||||
@@ -313,7 +309,6 @@ static Section *createSection(
|
|||||||
return §
|
return §
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new section fragment literal, not yet in the list.
|
|
||||||
static Section *createSectionFragmentLiteral(Section const &parent) {
|
static Section *createSectionFragmentLiteral(Section const &parent) {
|
||||||
// Add the new section to the list, but do not update the map
|
// Add the new section to the list, but do not update the map
|
||||||
Section § = sectionList.emplace_back();
|
Section § = sectionList.emplace_back();
|
||||||
@@ -339,7 +334,6 @@ static Section *createSectionFragmentLiteral(Section const &parent) {
|
|||||||
return §
|
return §
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find a section by name and type. If it doesn't exist, create it.
|
|
||||||
static Section *getSection(
|
static Section *getSection(
|
||||||
std::string const &name,
|
std::string const &name,
|
||||||
SectionType type,
|
SectionType type,
|
||||||
@@ -436,7 +430,6 @@ static Section *getSection(
|
|||||||
return sect;
|
return sect;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the current section
|
|
||||||
static void changeSection() {
|
static void changeSection() {
|
||||||
if (!currentUnionStack.empty()) {
|
if (!currentUnionStack.empty()) {
|
||||||
fatal("Cannot change the section within a UNION");
|
fatal("Cannot change the section within a UNION");
|
||||||
@@ -466,7 +459,6 @@ bool Section::isSizeKnown() const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the current section by name and type
|
|
||||||
void sect_NewSection(
|
void sect_NewSection(
|
||||||
std::string const &name,
|
std::string const &name,
|
||||||
SectionType type,
|
SectionType type,
|
||||||
@@ -492,7 +484,6 @@ void sect_NewSection(
|
|||||||
currentSection = sect;
|
currentSection = sect;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the current section by name and type
|
|
||||||
void sect_SetLoadSection(
|
void sect_SetLoadSection(
|
||||||
std::string const &name,
|
std::string const &name,
|
||||||
SectionType type,
|
SectionType type,
|
||||||
@@ -554,7 +545,6 @@ Section *sect_GetSymbolSection() {
|
|||||||
return currentLoadSection ? currentLoadSection : currentSection;
|
return currentLoadSection ? currentLoadSection : currentSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The offset into the section above
|
|
||||||
uint32_t sect_GetSymbolOffset() {
|
uint32_t sect_GetSymbolOffset() {
|
||||||
return curOffset;
|
return curOffset;
|
||||||
}
|
}
|
||||||
@@ -723,7 +713,6 @@ void sect_CheckUnionClosed() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a constant byte
|
|
||||||
void sect_ConstByte(uint8_t byte) {
|
void sect_ConstByte(uint8_t byte) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -732,7 +721,6 @@ void sect_ConstByte(uint8_t byte) {
|
|||||||
writeByte(byte);
|
writeByte(byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a string's character units as bytes
|
|
||||||
void sect_ByteString(std::vector<int32_t> const &string) {
|
void sect_ByteString(std::vector<int32_t> const &string) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -749,7 +737,6 @@ void sect_ByteString(std::vector<int32_t> const &string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a string's character units as words
|
|
||||||
void sect_WordString(std::vector<int32_t> const &string) {
|
void sect_WordString(std::vector<int32_t> const &string) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -766,7 +753,6 @@ void sect_WordString(std::vector<int32_t> const &string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a string's character units as longs
|
|
||||||
void sect_LongString(std::vector<int32_t> const &string) {
|
void sect_LongString(std::vector<int32_t> const &string) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -777,7 +763,6 @@ void sect_LongString(std::vector<int32_t> const &string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip this many bytes
|
|
||||||
void sect_Skip(uint32_t skip, bool ds) {
|
void sect_Skip(uint32_t skip, bool ds) {
|
||||||
if (!requireSection()) {
|
if (!requireSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -802,7 +787,6 @@ void sect_Skip(uint32_t skip, bool ds) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a byte that can be relocatable or constant
|
|
||||||
void sect_RelByte(Expression const &expr, uint32_t pcShift) {
|
void sect_RelByte(Expression const &expr, uint32_t pcShift) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -816,7 +800,6 @@ void sect_RelByte(Expression const &expr, uint32_t pcShift) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output several bytes that can be relocatable or constant
|
|
||||||
void sect_RelBytes(uint32_t n, std::vector<Expression> const &exprs) {
|
void sect_RelBytes(uint32_t n, std::vector<Expression> const &exprs) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -832,7 +815,6 @@ void sect_RelBytes(uint32_t n, std::vector<Expression> const &exprs) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a word that can be relocatable or constant
|
|
||||||
void sect_RelWord(Expression const &expr, uint32_t pcShift) {
|
void sect_RelWord(Expression const &expr, uint32_t pcShift) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -846,7 +828,6 @@ void sect_RelWord(Expression const &expr, uint32_t pcShift) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a long that can be relocatable or constant
|
|
||||||
void sect_RelLong(Expression const &expr, uint32_t pcShift) {
|
void sect_RelLong(Expression const &expr, uint32_t pcShift) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -860,7 +841,6 @@ void sect_RelLong(Expression const &expr, uint32_t pcShift) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a PC-relative byte that can be relocatable or constant
|
|
||||||
void sect_PCRelByte(Expression const &expr, uint32_t pcShift) {
|
void sect_PCRelByte(Expression const &expr, uint32_t pcShift) {
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
@@ -894,12 +874,7 @@ void sect_PCRelByte(Expression const &expr, uint32_t pcShift) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a binary file
|
void sect_BinaryFile(std::string const &name, uint32_t startPos) {
|
||||||
void sect_BinaryFile(std::string const &name, int32_t startPos) {
|
|
||||||
if (startPos < 0) {
|
|
||||||
error("Start position cannot be negative (%" PRId32 ")", startPos);
|
|
||||||
startPos = 0;
|
|
||||||
}
|
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -952,16 +927,7 @@ void sect_BinaryFile(std::string const &name, int32_t startPos) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output a slice of a binary file
|
void sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t length) {
|
||||||
void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t length) {
|
|
||||||
if (startPos < 0) {
|
|
||||||
error("Start position cannot be negative (%" PRId32 ")", startPos);
|
|
||||||
startPos = 0;
|
|
||||||
}
|
|
||||||
if (length < 0) {
|
|
||||||
error("Number of bytes to read cannot be negative (%" PRId32 ")", length);
|
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
if (!requireCodeSection()) {
|
if (!requireCodeSection()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -989,13 +955,13 @@ void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t len
|
|||||||
Defer closeFile{[&] { fclose(file); }};
|
Defer closeFile{[&] { fclose(file); }};
|
||||||
|
|
||||||
if (fseek(file, 0, SEEK_END) != -1) {
|
if (fseek(file, 0, SEEK_END) != -1) {
|
||||||
if (int32_t fsize = ftell(file); startPos > fsize) {
|
if (long fsize = ftell(file); startPos > fsize) {
|
||||||
error("Specified start position is greater than length of file '%s'", name.c_str());
|
error("Specified start position is greater than length of file '%s'", name.c_str());
|
||||||
return;
|
return;
|
||||||
} else if (startPos + length > fsize) {
|
} else if (startPos + length > fsize) {
|
||||||
error(
|
error(
|
||||||
"Specified range in INCBIN file '%s' is out of bounds (%" PRIu32 " + %" PRIu32
|
"Specified range in INCBIN file '%s' is out of bounds (%" PRIu32 " + %" PRIu32
|
||||||
" > %" PRIu32 ")",
|
" > %ld)",
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
startPos,
|
startPos,
|
||||||
length,
|
length,
|
||||||
@@ -1033,7 +999,6 @@ void sect_BinaryFileSlice(std::string const &name, int32_t startPos, int32_t len
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section stack routines
|
|
||||||
void sect_PushSection() {
|
void sect_PushSection() {
|
||||||
sectionStack.push_front({
|
sectionStack.push_front({
|
||||||
.section = currentSection,
|
.section = currentSection,
|
||||||
|
|||||||
3
test/asm/incbin-negative-bad.asm
Normal file
3
test/asm/incbin-negative-bad.asm
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
SECTION "Bad", ROM0
|
||||||
|
|
||||||
|
INCBIN "data.bin", -42
|
||||||
2
test/asm/incbin-negative-bad.err
Normal file
2
test/asm/incbin-negative-bad.err
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
FATAL: incbin-negative-bad.asm(3):
|
||||||
|
Constant must not be negative: -42
|
||||||
Reference in New Issue
Block a user