Distinguish EOF and empty lines when parsing text pal files

This commit is contained in:
ISSOtm
2024-07-26 14:58:36 +02:00
committed by Sylvie
parent 3bd35a8848
commit a23b4732e3
5 changed files with 25 additions and 13 deletions

View File

@@ -176,6 +176,7 @@ void parseInlinePalSpec(char const * const rawArg) {
* Returns whether the magic was correctly read. * Returns whether the magic was correctly read.
*/ */
template<size_t n> template<size_t n>
[[gnu::warn_unused_result]] // Ignoring failure to match is a bad idea.
static bool readMagic(std::filebuf &file, char const *magic) { static bool readMagic(std::filebuf &file, char const *magic) {
assume(strlen(magic) == n); assume(strlen(magic) == n);
@@ -203,26 +204,36 @@ static T readLE(U const *bytes) {
/* /*
* **Appends** the first line read from `file` to the end of the provided `buffer`. * **Appends** the first line read from `file` to the end of the provided `buffer`.
*
* @return true if a line was read.
*/ */
static void readLine(std::filebuf &file, std::string &buffer) { [[gnu::warn_unused_result]] // Ignoring EOF is a bad idea.
static bool readLine(std::filebuf &file, std::string &buffer) {
// TODO: maybe this can be optimized to bulk reads? // TODO: maybe this can be optimized to bulk reads?
for (;;) { for (;;) {
auto c = file.sbumpc(); auto c = file.sbumpc();
if (c == std::filebuf::traits_type::eof()) { if (c == std::filebuf::traits_type::eof()) {
return; return false;
} }
if (c == '\n') { if (c == '\n') {
// Discard a trailing CRLF // Discard a trailing CRLF
if (!buffer.empty() && buffer.back() == '\r') { if (!buffer.empty() && buffer.back() == '\r') {
buffer.pop_back(); buffer.pop_back();
} }
return; return true;
} }
buffer.push_back(c); buffer.push_back(c);
} }
} }
#define requireLine(kind, file, buffer) do { \
if (!readLine(file, buffer)) { \
error(kind " palette file is shorter than expected"); \
return; \
} \
} while (0)
/* /*
* Parses the initial part of a string_view, advancing the "read index" as it does * Parses the initial part of a string_view, advancing the "read index" as it does
*/ */
@@ -272,21 +283,20 @@ static void parsePSPFile(std::filebuf &file) {
// https://www.selapa.net/swatches/colors/fileformats.php#psp_pal // https://www.selapa.net/swatches/colors/fileformats.php#psp_pal
std::string line; std::string line;
readLine(file, line); if (!readLine(file, line) || line != "JASC-PAL") {
if (line != "JASC-PAL") {
error("Palette file does not appear to be a PSP palette file"); error("Palette file does not appear to be a PSP palette file");
return; return;
} }
line.clear(); line.clear();
readLine(file, line); requireLine("PSP", file, line);
if (line != "0100") { if (line != "0100") {
error("Unsupported PSP palette file version \"%s\"", line.c_str()); error("Unsupported PSP palette file version \"%s\"", line.c_str());
return; return;
} }
line.clear(); line.clear();
readLine(file, line); requireLine("PSP", file, line);
std::string::size_type n = 0; std::string::size_type n = 0;
std::optional<uint16_t> nbColors = parseDec<uint16_t>(line, n); std::optional<uint16_t> nbColors = parseDec<uint16_t>(line, n);
if (!nbColors || n != line.length()) { if (!nbColors || n != line.length()) {
@@ -309,7 +319,7 @@ static void parsePSPFile(std::filebuf &file) {
for (uint16_t i = 0; i < *nbColors; ++i) { for (uint16_t i = 0; i < *nbColors; ++i) {
line.clear(); line.clear();
readLine(file, line); requireLine("PSP", file, line);
n = 0; n = 0;
std::optional<Rgba> color = parseColor(line, n, i + 1); std::optional<Rgba> color = parseColor(line, n, i + 1);
@@ -336,8 +346,7 @@ static void parseGPLFile(std::filebuf &file) {
// https://gitlab.gnome.org/GNOME/gimp/-/blob/gimp-2-10/app/core/gimppalette-load.c#L39 // https://gitlab.gnome.org/GNOME/gimp/-/blob/gimp-2-10/app/core/gimppalette-load.c#L39
std::string line; std::string line;
readLine(file, line); if (!readLine(file, line) || !line.starts_with("GIMP Palette")) {
if (!line.starts_with("GIMP Palette")) {
error("Palette file does not appear to be a GPL palette file"); error("Palette file does not appear to be a GPL palette file");
return; return;
} }
@@ -347,7 +356,7 @@ static void parseGPLFile(std::filebuf &file) {
for (;;) { for (;;) {
line.clear(); line.clear();
readLine(file, line); requireLine("GPL", file, line);
if (!line.length()) { if (!line.length()) {
break; break;
} }
@@ -389,8 +398,7 @@ static void parseHEXFile(std::filebuf &file) {
for (;;) { for (;;) {
std::string line; std::string line;
readLine(file, line); if (!readLine(file, line)) {
if (!line.length()) {
break; break;
} }

View File

@@ -0,0 +1,2 @@
error: GPL palette file appears to be truncated
Conversion aborted after 1 error

View File

@@ -0,0 +1 @@
-c gpl:truncated_gpl.gpl

View File

@@ -0,0 +1 @@
GIMP Palette

BIN
test/gfx/truncated_gpl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 712 B