mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-27 16:10:48 +01:00
cleanup: secure reading some stream names
This commit is contained in:
parent
4e9d4905d9
commit
25d2ecb59b
@ -243,7 +243,7 @@ VGMSTREAM* init_vgmstream_nus3bank(STREAMFILE* sf) {
|
||||
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
if (name_offset)
|
||||
read_string(vgmstream->stream_name, name_size, name_offset, sf);
|
||||
read_string_sz(vgmstream->stream_name, STREAM_NAME_SIZE, name_size, name_offset, sf);
|
||||
|
||||
|
||||
close_streamfile(temp_sf);
|
||||
|
@ -197,7 +197,7 @@ VGMSTREAM* init_vgmstream_sqex_scd(STREAMFILE* sf) {
|
||||
/* actual Ogg init */
|
||||
ogg_vgmstream = init_vgmstream_ogg_vorbis_config(sf, start_offset, &ovmi);
|
||||
if (ogg_vgmstream && name_offset)
|
||||
read_string(ogg_vgmstream->stream_name, PATH_LIMIT, name_offset, sf);
|
||||
read_string(ogg_vgmstream->stream_name, STREAM_NAME_SIZE, name_offset, sf);
|
||||
return ogg_vgmstream;
|
||||
}
|
||||
#endif
|
||||
|
@ -339,58 +339,45 @@ static void sead_cat(char* dst, int dst_max, const char* src) {
|
||||
}
|
||||
|
||||
static void build_readable_sab_name(sead_header_t* sead, STREAMFILE* sf, uint32_t sndname_offset, uint32_t sndname_size) {
|
||||
char * buf = sead->readable_name;
|
||||
char* buf = sead->readable_name;
|
||||
int buf_size = sizeof(sead->readable_name);
|
||||
char descriptor[255], name[255];
|
||||
|
||||
if (sead->filename_size > 255 || sndname_size > 255)
|
||||
goto fail;
|
||||
char descriptor[256], name[256];
|
||||
|
||||
if (buf[0] == '\0') { /* init */
|
||||
read_string(descriptor,sead->filename_size+1, sead->filename_offset, sf);
|
||||
read_string(name, sndname_size+1, sndname_offset, sf);
|
||||
read_string_sz(descriptor, sizeof(descriptor), sead->filename_size, sead->filename_offset, sf);
|
||||
read_string_sz(name, sizeof(name), sndname_size, sndname_offset, sf);
|
||||
|
||||
snprintf(buf,buf_size, "%s/%s", descriptor, name);
|
||||
}
|
||||
else { /* add */
|
||||
read_string(name, sndname_size+1, sndname_offset, sf);
|
||||
read_string_sz(name, sizeof(name), sndname_size, sndname_offset, sf);
|
||||
|
||||
sead_cat(buf, buf_size, "; ");
|
||||
sead_cat(buf, buf_size, name);
|
||||
}
|
||||
return;
|
||||
fail:
|
||||
VGM_LOG("SEAD: bad sab name found\n");
|
||||
}
|
||||
|
||||
static void build_readable_mab_name(sead_header_t* sead, STREAMFILE* sf) {
|
||||
char * buf = sead->readable_name;
|
||||
char* buf = sead->readable_name;
|
||||
int buf_size = sizeof(sead->readable_name);
|
||||
char descriptor[255], name[255], mode[255];
|
||||
char descriptor[256], name[256], mode[256];
|
||||
|
||||
if (sead->filename_size > 255 || sead->muscname_size > 255 || sead->sectname_size > 255 || sead->modename_size > 255)
|
||||
goto fail;
|
||||
|
||||
read_string(descriptor,sead->filename_size+1,sead->filename_offset, sf);
|
||||
//read_string(filename,sead->muscname_size+1,sead->muscname_offset, sf); /* same as filename, not too interesting */
|
||||
read_string_sz(descriptor, sizeof(descriptor), sead->filename_size, sead->filename_offset, sf);
|
||||
//read_string_sz(filename, sizeof(filename), sead->muscname_size, sead->muscname_offset, sf); /* same as filename, not too interesting */
|
||||
if (sead->sectname_offset)
|
||||
read_string(name,sead->sectname_size+1,sead->sectname_offset, sf);
|
||||
read_string_sz(name, sizeof(name), sead->sectname_size,sead->sectname_offset, sf);
|
||||
else if (sead->instname_offset)
|
||||
read_string(name,sead->instname_size+1,sead->instname_offset, sf);
|
||||
read_string_sz(name, sizeof(name), sead->instname_size, sead->instname_offset, sf);
|
||||
else
|
||||
strcpy(name, "?");
|
||||
if (sead->modename_offset > 0)
|
||||
read_string(mode,sead->modename_size+1,sead->modename_offset, sf);
|
||||
read_string_sz(mode, sizeof(mode), sead->modename_size,sead->modename_offset, sf);
|
||||
|
||||
/* default mode in most files */
|
||||
if (sead->modename_offset == 0 || strcmp(mode, "Mode") == 0 || strcmp(mode, "Mode0") == 0)
|
||||
snprintf(buf,buf_size, "%s/%s", descriptor, name);
|
||||
else
|
||||
snprintf(buf,buf_size, "%s/%s/%s", descriptor, name, mode);
|
||||
|
||||
return;
|
||||
fail:
|
||||
VGM_LOG("SEAD: bad mab name found\n");
|
||||
}
|
||||
|
||||
static void parse_sead_mab_name(sead_header_t* sead, STREAMFILE* sf) {
|
||||
|
@ -120,29 +120,41 @@ size_t read_bom(STREAMFILE* sf) {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
|
||||
size_t pos;
|
||||
size_t read_string_sz(char* buf, size_t buf_size, size_t string_size, off_t offset, STREAMFILE* sf) {
|
||||
|
||||
for (pos = 0; pos < buf_size; pos++) {
|
||||
// read up to buf, or stop before if size is set; in either case will stop at 0x00
|
||||
size_t max_size = buf_size;
|
||||
if (string_size > 0 && string_size < max_size)
|
||||
max_size = string_size + 1;
|
||||
|
||||
for (size_t pos = 0; pos < max_size; pos++) {
|
||||
uint8_t byte = read_u8(offset + pos, sf);
|
||||
char c = (char)byte;
|
||||
if (buf) buf[pos] = c;
|
||||
if (c == '\0')
|
||||
if (buf) buf[pos] = (char)byte;
|
||||
|
||||
// done
|
||||
if (byte == '\0')
|
||||
return pos;
|
||||
if (pos+1 == buf_size) { /* null at maxsize and don't validate (expected to be garbage) */
|
||||
|
||||
// null at maxsize and don't validate (expected to be garbage)
|
||||
if (pos + 1 == max_size) {
|
||||
if (buf) buf[pos] = '\0';
|
||||
return buf_size;
|
||||
return max_size;
|
||||
}
|
||||
/* UTF-8 only goes to 0x7F, but allow a bunch of Windows-1252 codes that some games use */
|
||||
|
||||
// UTF-8 only goes to 0x7F, but allow a bunch of Windows-1252 codes that some games use
|
||||
if (byte < 0x20 || byte > 0xF0)
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
|
||||
fail:
|
||||
// error or wrong max_size
|
||||
if (buf) buf[0] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf) {
|
||||
return read_string_sz(buf, buf_size, 0, offset, sf);
|
||||
}
|
||||
|
||||
size_t read_string_utf16(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf, int big_endian) {
|
||||
size_t pos, offpos;
|
||||
read_u16_t read_u16 = big_endian ? read_u16be : read_u16le;
|
||||
|
@ -11,7 +11,10 @@ size_t read_line(char* buf, int buf_size, off_t offset, STREAMFILE* sf, int* p_l
|
||||
/* skip BOM if needed */
|
||||
size_t read_bom(STREAMFILE* sf);
|
||||
|
||||
/* reads a c-string (ANSI only), up to bufsize or NULL, returning size. buf is optional (works as get_string_size). */
|
||||
/* Reads a C-string (ANSI only), up to buf_size, string_size (no need to include null char), or NULL (whichever is happens first).
|
||||
* Returning size and buf is optional (works as get_string_size without it). Will always null-terminate the string. */
|
||||
size_t read_string_sz(char* buf, size_t buf_size, size_t string_size, off_t offset, STREAMFILE* sf);
|
||||
/* same but without known string_size */
|
||||
size_t read_string(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf);
|
||||
/* reads a UTF16 string... but actually only as ANSI (discards the upper byte) */
|
||||
size_t read_string_utf16(char* buf, size_t buf_size, off_t offset, STREAMFILE* sf, int big_endian);
|
||||
|
Loading…
Reference in New Issue
Block a user