mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-05-31 00:30:57 +00:00
Don't read past the end of a sub-file.
This fixes a libvobis streaming problem with vorbis files within pak files.
This commit is contained in:
parent
341726afb9
commit
98a5d591d5
1 changed files with 43 additions and 2 deletions
|
@ -84,7 +84,9 @@ struct QFile_s {
|
||||||
#endif
|
#endif
|
||||||
off_t size;
|
off_t size;
|
||||||
off_t start;
|
off_t start;
|
||||||
|
off_t pos;
|
||||||
int c;
|
int c;
|
||||||
|
int sub;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -289,6 +291,7 @@ Qsubopen (const char *path, int offs, int len, int zip)
|
||||||
file = Qdopen (fd, zip ? "rbz" : "rb");
|
file = Qdopen (fd, zip ? "rbz" : "rb");
|
||||||
file->size = len;
|
file->size = len;
|
||||||
file->start = offs;
|
file->start = offs;
|
||||||
|
file->sub = 1;
|
||||||
return file;
|
return file;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +320,19 @@ Qread (QFile *file, void *buf, int count)
|
||||||
offs = 1;
|
offs = 1;
|
||||||
file->c = -1;
|
file->c = -1;
|
||||||
count--;
|
count--;
|
||||||
|
if (!count)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (file->sub) {
|
||||||
|
// sub-files are always opened in binary mode, so we don't need to
|
||||||
|
// worry about character translation messing up count/pos. Normal
|
||||||
|
// files can be left to the operating system to take care of EOF.
|
||||||
|
if (file->pos + count > file->size)
|
||||||
|
count = file->size - file->pos;
|
||||||
|
if (count < 0)
|
||||||
|
return -1;
|
||||||
|
if (!count)
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
if (file->file)
|
if (file->file)
|
||||||
ret = fread (buf, 1, count, file->file);
|
ret = fread (buf, 1, count, file->file);
|
||||||
|
@ -326,12 +342,16 @@ Qread (QFile *file, void *buf, int count)
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
if (file->sub)
|
||||||
|
file->pos += ret;
|
||||||
return ret == -1 ? ret : ret + offs;
|
return ret == -1 ? ret : ret + offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
VISIBLE int
|
VISIBLE int
|
||||||
Qwrite (QFile *file, const void *buf, int count)
|
Qwrite (QFile *file, const void *buf, int count)
|
||||||
{
|
{
|
||||||
|
if (file->sub) // can't write to a sub-file
|
||||||
|
return -1;
|
||||||
if (file->file)
|
if (file->file)
|
||||||
return fwrite (buf, 1, count, file->file);
|
return fwrite (buf, 1, count, file->file);
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
|
@ -348,6 +368,8 @@ Qprintf (QFile *file, const char *fmt, ...)
|
||||||
va_list args;
|
va_list args;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
|
if (file->sub) // can't write to a sub-file
|
||||||
|
return -1;
|
||||||
va_start (args, fmt);
|
va_start (args, fmt);
|
||||||
if (file->file)
|
if (file->file)
|
||||||
ret = vfprintf (file->file, fmt, args);
|
ret = vfprintf (file->file, fmt, args);
|
||||||
|
@ -373,6 +395,8 @@ Qprintf (QFile *file, const char *fmt, ...)
|
||||||
VISIBLE int
|
VISIBLE int
|
||||||
Qputs (QFile *file, const char *buf)
|
Qputs (QFile *file, const char *buf)
|
||||||
{
|
{
|
||||||
|
if (file->sub) // can't write to a sub-file
|
||||||
|
return -1;
|
||||||
if (file->file)
|
if (file->file)
|
||||||
return fputs (buf, file->file);
|
return fputs (buf, file->file);
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
|
@ -412,6 +436,11 @@ Qgetc (QFile *file)
|
||||||
file->c = -1;
|
file->c = -1;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
if (file->sub) {
|
||||||
|
if (file->pos >= file->size)
|
||||||
|
return EOF;
|
||||||
|
file->pos++;
|
||||||
|
}
|
||||||
if (file->file)
|
if (file->file)
|
||||||
return fgetc (file->file);
|
return fgetc (file->file);
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
|
@ -425,6 +454,8 @@ Qgetc (QFile *file)
|
||||||
VISIBLE int
|
VISIBLE int
|
||||||
Qputc (QFile *file, int c)
|
Qputc (QFile *file, int c)
|
||||||
{
|
{
|
||||||
|
if (file->sub) // can't write to a sub-file
|
||||||
|
return -1;
|
||||||
if (file->file)
|
if (file->file)
|
||||||
return fputc (c, file->file);
|
return fputc (c, file->file);
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
|
@ -446,9 +477,10 @@ Qungetc (QFile *file, int c)
|
||||||
VISIBLE int
|
VISIBLE int
|
||||||
Qseek (QFile *file, long offset, int whence)
|
Qseek (QFile *file, long offset, int whence)
|
||||||
{
|
{
|
||||||
|
int res;
|
||||||
|
|
||||||
file->c = -1;
|
file->c = -1;
|
||||||
if (file->file) {
|
if (file->file) {
|
||||||
int res;
|
|
||||||
switch (whence) {
|
switch (whence) {
|
||||||
case SEEK_SET:
|
case SEEK_SET:
|
||||||
res = fseek (file->file, file->start + offset, whence);
|
res = fseek (file->file, file->start + offset, whence);
|
||||||
|
@ -472,13 +504,18 @@ Qseek (QFile *file, long offset, int whence)
|
||||||
}
|
}
|
||||||
if (res != -1)
|
if (res != -1)
|
||||||
res = ftell (file->file) - file->start;
|
res = ftell (file->file) - file->start;
|
||||||
|
if (file->sub)
|
||||||
|
file->pos = res;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
else {
|
else {
|
||||||
// libz seems to keep track of the true start position itself
|
// libz seems to keep track of the true start position itself
|
||||||
// doesn't support SEEK_END, though
|
// doesn't support SEEK_END, though
|
||||||
return gzseek (file->gzfile, offset, whence);
|
res = gzseek (file->gzfile, offset, whence);
|
||||||
|
if (file->sub)
|
||||||
|
file->pos = res;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -500,6 +537,8 @@ Qtell (QFile *file)
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
|
if (file->sub)
|
||||||
|
file->pos = ret;
|
||||||
return ret == -1 ? ret : ret - offs;
|
return ret == -1 ? ret : ret - offs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,6 +560,8 @@ Qeof (QFile *file)
|
||||||
{
|
{
|
||||||
if (file->c != -1)
|
if (file->c != -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
if (file->sub)
|
||||||
|
return file->pos >= file->size;
|
||||||
if (file->file)
|
if (file->file)
|
||||||
return feof (file->file);
|
return feof (file->file);
|
||||||
#ifdef HAVE_ZLIB
|
#ifdef HAVE_ZLIB
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue