Fixes crash when resource file is corrupted
(cherry picked from commit 832a5c860b
)
This commit is contained in:
parent
f0c89048d8
commit
c81241e6c0
2 changed files with 33 additions and 16 deletions
|
@ -63,6 +63,10 @@ Error FileAccessCompressed::open_after_magic(FileAccess *p_base) {
|
||||||
f = p_base;
|
f = p_base;
|
||||||
cmode = (Compression::Mode)f->get_32();
|
cmode = (Compression::Mode)f->get_32();
|
||||||
block_size = f->get_32();
|
block_size = f->get_32();
|
||||||
|
if (block_size == 0) {
|
||||||
|
f = NULL; // Let the caller to handle the FileAccess object if failed to open as compressed file.
|
||||||
|
ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Can't open compressed file '" + p_base->get_path() + "' with block size 0, it is corrupted.");
|
||||||
|
}
|
||||||
read_total = f->get_32();
|
read_total = f->get_32();
|
||||||
int bc = (read_total / block_size) + 1;
|
int bc = (read_total / block_size) + 1;
|
||||||
int acc_ofs = f->get_position() + bc * 4;
|
int acc_ofs = f->get_position() + bc * 4;
|
||||||
|
@ -125,13 +129,11 @@ Error FileAccessCompressed::_open(const String &p_path, int p_mode_flags) {
|
||||||
char rmagic[5];
|
char rmagic[5];
|
||||||
f->get_buffer((uint8_t *)rmagic, 4);
|
f->get_buffer((uint8_t *)rmagic, 4);
|
||||||
rmagic[4] = 0;
|
rmagic[4] = 0;
|
||||||
if (magic != rmagic) {
|
if (magic != rmagic || open_after_magic(f) != OK) {
|
||||||
memdelete(f);
|
memdelete(f);
|
||||||
f = NULL;
|
f = NULL;
|
||||||
return ERR_FILE_UNRECOGNIZED;
|
return ERR_FILE_UNRECOGNIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
open_after_magic(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
|
|
|
@ -836,15 +836,20 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
|
||||||
uint8_t header[4];
|
uint8_t header[4];
|
||||||
f->get_buffer(header, 4);
|
f->get_buffer(header, 4);
|
||||||
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
||||||
//compressed
|
// Compressed.
|
||||||
FileAccessCompressed *fac = memnew(FileAccessCompressed);
|
FileAccessCompressed *fac = memnew(FileAccessCompressed);
|
||||||
fac->open_after_magic(f);
|
error = fac->open_after_magic(f);
|
||||||
|
if (error != OK) {
|
||||||
|
memdelete(fac);
|
||||||
|
f->close();
|
||||||
|
ERR_FAIL_MSG("Failed to open binary resource file: " + local_path + ".");
|
||||||
|
}
|
||||||
f = fac;
|
f = fac;
|
||||||
|
|
||||||
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
||||||
//not normal
|
// Not normal.
|
||||||
|
|
||||||
error = ERR_FILE_UNRECOGNIZED;
|
error = ERR_FILE_UNRECOGNIZED;
|
||||||
|
f->close();
|
||||||
ERR_FAIL_MSG("Unrecognized binary resource file: " + local_path + ".");
|
ERR_FAIL_MSG("Unrecognized binary resource file: " + local_path + ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -919,6 +924,7 @@ void ResourceInteractiveLoaderBinary::open(FileAccess *p_f) {
|
||||||
if (f->eof_reached()) {
|
if (f->eof_reached()) {
|
||||||
|
|
||||||
error = ERR_FILE_CORRUPT;
|
error = ERR_FILE_CORRUPT;
|
||||||
|
f->close();
|
||||||
ERR_FAIL_MSG("Premature end of file (EOF): " + local_path + ".");
|
ERR_FAIL_MSG("Premature end of file (EOF): " + local_path + ".");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -931,14 +937,20 @@ String ResourceInteractiveLoaderBinary::recognize(FileAccess *p_f) {
|
||||||
uint8_t header[4];
|
uint8_t header[4];
|
||||||
f->get_buffer(header, 4);
|
f->get_buffer(header, 4);
|
||||||
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
||||||
//compressed
|
// Compressed.
|
||||||
FileAccessCompressed *fac = memnew(FileAccessCompressed);
|
FileAccessCompressed *fac = memnew(FileAccessCompressed);
|
||||||
fac->open_after_magic(f);
|
error = fac->open_after_magic(f);
|
||||||
|
if (error != OK) {
|
||||||
|
memdelete(fac);
|
||||||
|
f->close();
|
||||||
|
return "";
|
||||||
|
}
|
||||||
f = fac;
|
f = fac;
|
||||||
|
|
||||||
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
||||||
//not normal
|
// Not normal.
|
||||||
error = ERR_FILE_UNRECOGNIZED;
|
error = ERR_FILE_UNRECOGNIZED;
|
||||||
|
f->close();
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1055,14 +1067,19 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
|
||||||
uint8_t header[4];
|
uint8_t header[4];
|
||||||
f->get_buffer(header, 4);
|
f->get_buffer(header, 4);
|
||||||
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
if (header[0] == 'R' && header[1] == 'S' && header[2] == 'C' && header[3] == 'C') {
|
||||||
//compressed
|
// Compressed.
|
||||||
FileAccessCompressed *fac = memnew(FileAccessCompressed);
|
FileAccessCompressed *fac = memnew(FileAccessCompressed);
|
||||||
fac->open_after_magic(f);
|
Error err = fac->open_after_magic(f);
|
||||||
|
if (err != OK) {
|
||||||
|
memdelete(fac);
|
||||||
|
memdelete(f);
|
||||||
|
ERR_FAIL_V_MSG(err, "Cannot open file '" + p_path + "'.");
|
||||||
|
}
|
||||||
f = fac;
|
f = fac;
|
||||||
|
|
||||||
FileAccessCompressed *facw = memnew(FileAccessCompressed);
|
FileAccessCompressed *facw = memnew(FileAccessCompressed);
|
||||||
facw->configure("RSCC");
|
facw->configure("RSCC");
|
||||||
Error err = facw->_open(p_path + ".depren", FileAccess::WRITE);
|
err = facw->_open(p_path + ".depren", FileAccess::WRITE);
|
||||||
if (err) {
|
if (err) {
|
||||||
memdelete(fac);
|
memdelete(fac);
|
||||||
memdelete(facw);
|
memdelete(facw);
|
||||||
|
@ -1072,9 +1089,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons
|
||||||
fw = facw;
|
fw = facw;
|
||||||
|
|
||||||
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
} else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') {
|
||||||
//not normal
|
// Not normal.
|
||||||
|
|
||||||
//error=ERR_FILE_UNRECOGNIZED;
|
|
||||||
memdelete(f);
|
memdelete(f);
|
||||||
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unrecognized binary resource file '" + local_path + "'.");
|
ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unrecognized binary resource file '" + local_path + "'.");
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in a new issue