mirror of
https://github.com/gbdev/rgbds.git
synced 2026-09-13 17:27:06 +00:00
Encapsulate fseek+ftell idiom in seekSize
This allows a single check for the return value of `seekSize` to verify all three `fseek`+`ftell`+`fseek` calls.
This commit is contained in:
@@ -26,6 +26,9 @@ enum NumberBase {
|
|||||||
int xfclose(FILE *file);
|
int xfclose(FILE *file);
|
||||||
int xclose(int fd);
|
int xclose(int fd);
|
||||||
|
|
||||||
|
// Measure file size with `fseek` and `ftell` idiom
|
||||||
|
long seekSize(FILE *file);
|
||||||
|
|
||||||
// Locale-independent character class functions
|
// Locale-independent character class functions
|
||||||
bool isNewline(int c);
|
bool isNewline(int c);
|
||||||
bool isBlankSpace(int c);
|
bool isBlankSpace(int c);
|
||||||
|
|||||||
+3
-4
@@ -18,7 +18,7 @@
|
|||||||
#include "extern/utf8decoder.hpp"
|
#include "extern/utf8decoder.hpp"
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "linkdefs.hpp"
|
#include "linkdefs.hpp"
|
||||||
#include "util.hpp" // xfclose
|
#include "util.hpp" // xfclose, seekSize
|
||||||
|
|
||||||
#include "asm/charmap.hpp"
|
#include "asm/charmap.hpp"
|
||||||
#include "asm/format.hpp"
|
#include "asm/format.hpp"
|
||||||
@@ -151,13 +151,12 @@ std::optional<std::string> act_ReadFile(std::string const &name, uint32_t maxLen
|
|||||||
Defer closeFile{[&] { xfclose(file); }};
|
Defer closeFile{[&] { xfclose(file); }};
|
||||||
|
|
||||||
size_t readSize = maxLen;
|
size_t readSize = maxLen;
|
||||||
if (fseek(file, 0, SEEK_END) == 0) {
|
if (long fileSize = seekSize(file); fileSize != -1) {
|
||||||
// If the file is seekable and shorter than the max length,
|
// If the file is seekable and shorter than the max length,
|
||||||
// just read as many bytes as there are
|
// just read as many bytes as there are
|
||||||
if (long fileSize = ftell(file); static_cast<size_t>(fileSize) < readSize) {
|
if (static_cast<size_t>(fileSize) < readSize) {
|
||||||
readSize = fileSize;
|
readSize = fileSize;
|
||||||
}
|
}
|
||||||
fseek(file, 0, SEEK_SET);
|
|
||||||
// LCOV_EXCL_START
|
// LCOV_EXCL_START
|
||||||
} else if (errno != ESPIPE) {
|
} else if (errno != ESPIPE) {
|
||||||
error(
|
error(
|
||||||
|
|||||||
+11
-13
@@ -21,7 +21,7 @@
|
|||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "itertools.hpp" // InsertionOrderedMap
|
#include "itertools.hpp" // InsertionOrderedMap
|
||||||
#include "linkdefs.hpp"
|
#include "linkdefs.hpp"
|
||||||
#include "util.hpp" // xfclose
|
#include "util.hpp" // xfclose, seekSize
|
||||||
|
|
||||||
#include "asm/fstack.hpp"
|
#include "asm/fstack.hpp"
|
||||||
#include "asm/lexer.hpp"
|
#include "asm/lexer.hpp"
|
||||||
@@ -977,14 +977,13 @@ bool sect_BinaryFile(std::string const &name, uint32_t startPos) {
|
|||||||
}
|
}
|
||||||
Defer closeFile{[&] { xfclose(file); }};
|
Defer closeFile{[&] { xfclose(file); }};
|
||||||
|
|
||||||
if (fseek(file, 0, SEEK_END) == 0) {
|
if (long fileSize = seekSize(file); fileSize != -1) {
|
||||||
if (unsigned long fsize = ftell(file);
|
if (startPos > static_cast<size_t>(fileSize)) {
|
||||||
startPos > fsize) { // `ftell` cannot fail here, since `fseek` succeeded.
|
|
||||||
error(
|
error(
|
||||||
"Specified start position (%" PRIu32 ") is greater than length of \"%s\" (%lu)",
|
"Specified start position (%" PRIu32 ") is greater than length of \"%s\" (%ld)",
|
||||||
startPos,
|
startPos,
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
fsize
|
fileSize
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1038,24 +1037,23 @@ bool sect_BinaryFileSlice(std::string const &name, uint32_t startPos, uint32_t l
|
|||||||
}
|
}
|
||||||
Defer closeFile{[&] { xfclose(file); }};
|
Defer closeFile{[&] { xfclose(file); }};
|
||||||
|
|
||||||
if (fseek(file, 0, SEEK_END) == 0) {
|
if (long fileSize = seekSize(file); fileSize != -1) {
|
||||||
if (unsigned long fsize = ftell(file);
|
if (startPos > static_cast<size_t>(fileSize)) {
|
||||||
startPos > fsize) { // `ftell` cannot fail here, since `fseek` succeeded.
|
|
||||||
error(
|
error(
|
||||||
"Specified start position (%" PRIu32 ") is greater than length of \"%s\" (%lu)",
|
"Specified start position (%" PRIu32 ") is greater than length of \"%s\" (%ld)",
|
||||||
startPos,
|
startPos,
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
fsize
|
fileSize
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
} else if (startPos + length > fsize) {
|
} else if (startPos + length > static_cast<size_t>(fileSize)) {
|
||||||
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
|
||||||
" > %ld)",
|
" > %ld)",
|
||||||
name.c_str(),
|
name.c_str(),
|
||||||
startPos,
|
startPos,
|
||||||
length,
|
length,
|
||||||
fsize
|
fileSize
|
||||||
);
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-6
@@ -112,16 +112,13 @@ static uint32_t checkOverlaySize() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fseek(overlayFile, 0, SEEK_END) != 0) {
|
long overlaySize = seekSize(overlayFile);
|
||||||
|
|
||||||
|
if (overlaySize == -1) {
|
||||||
warnx("Overlay file is not seekable, cannot check if properly formed");
|
warnx("Overlay file is not seekable, cannot check if properly formed");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
long overlaySize = ftell(overlayFile);
|
|
||||||
|
|
||||||
// Reset back to beginning
|
|
||||||
fseek(overlayFile, 0, SEEK_SET);
|
|
||||||
|
|
||||||
if (overlaySize % BANK_SIZE) {
|
if (overlaySize % BANK_SIZE) {
|
||||||
warnx("Overlay file does not have a size multiple of 0x4000");
|
warnx("Overlay file does not have a size multiple of 0x4000");
|
||||||
} else if (options.is32kMode && overlaySize != 0x8000) {
|
} else if (options.is32kMode && overlaySize != 0x8000) {
|
||||||
|
|||||||
@@ -25,6 +25,20 @@ int xclose(int fd) {
|
|||||||
return close(fd);
|
return close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long seekSize(FILE *file) {
|
||||||
|
if (fseek(file, 0, SEEK_END) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
long size = ftell(file);
|
||||||
|
if (size < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (fseek(file, 0, SEEK_SET) != 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
bool isNewline(int c) {
|
bool isNewline(int c) {
|
||||||
return c == '\r' || c == '\n';
|
return c == '\r' || c == '\n';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user