mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-22 02:11:19 +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
|
||||
off_t size;
|
||||
off_t start;
|
||||
off_t pos;
|
||||
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->size = len;
|
||||
file->start = offs;
|
||||
file->sub = 1;
|
||||
return file;
|
||||
}
|
||||
|
||||
|
@ -317,6 +320,19 @@ Qread (QFile *file, void *buf, int count)
|
|||
offs = 1;
|
||||
file->c = -1;
|
||||
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)
|
||||
ret = fread (buf, 1, count, file->file);
|
||||
|
@ -326,12 +342,16 @@ Qread (QFile *file, void *buf, int count)
|
|||
#else
|
||||
return -1;
|
||||
#endif
|
||||
if (file->sub)
|
||||
file->pos += ret;
|
||||
return ret == -1 ? ret : ret + offs;
|
||||
}
|
||||
|
||||
VISIBLE int
|
||||
Qwrite (QFile *file, const void *buf, int count)
|
||||
{
|
||||
if (file->sub) // can't write to a sub-file
|
||||
return -1;
|
||||
if (file->file)
|
||||
return fwrite (buf, 1, count, file->file);
|
||||
#ifdef HAVE_ZLIB
|
||||
|
@ -348,6 +368,8 @@ Qprintf (QFile *file, const char *fmt, ...)
|
|||
va_list args;
|
||||
int ret = -1;
|
||||
|
||||
if (file->sub) // can't write to a sub-file
|
||||
return -1;
|
||||
va_start (args, fmt);
|
||||
if (file->file)
|
||||
ret = vfprintf (file->file, fmt, args);
|
||||
|
@ -373,6 +395,8 @@ Qprintf (QFile *file, const char *fmt, ...)
|
|||
VISIBLE int
|
||||
Qputs (QFile *file, const char *buf)
|
||||
{
|
||||
if (file->sub) // can't write to a sub-file
|
||||
return -1;
|
||||
if (file->file)
|
||||
return fputs (buf, file->file);
|
||||
#ifdef HAVE_ZLIB
|
||||
|
@ -412,6 +436,11 @@ Qgetc (QFile *file)
|
|||
file->c = -1;
|
||||
return c;
|
||||
}
|
||||
if (file->sub) {
|
||||
if (file->pos >= file->size)
|
||||
return EOF;
|
||||
file->pos++;
|
||||
}
|
||||
if (file->file)
|
||||
return fgetc (file->file);
|
||||
#ifdef HAVE_ZLIB
|
||||
|
@ -425,6 +454,8 @@ Qgetc (QFile *file)
|
|||
VISIBLE int
|
||||
Qputc (QFile *file, int c)
|
||||
{
|
||||
if (file->sub) // can't write to a sub-file
|
||||
return -1;
|
||||
if (file->file)
|
||||
return fputc (c, file->file);
|
||||
#ifdef HAVE_ZLIB
|
||||
|
@ -446,9 +477,10 @@ Qungetc (QFile *file, int c)
|
|||
VISIBLE int
|
||||
Qseek (QFile *file, long offset, int whence)
|
||||
{
|
||||
int res;
|
||||
|
||||
file->c = -1;
|
||||
if (file->file) {
|
||||
int res;
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
res = fseek (file->file, file->start + offset, whence);
|
||||
|
@ -472,13 +504,18 @@ Qseek (QFile *file, long offset, int whence)
|
|||
}
|
||||
if (res != -1)
|
||||
res = ftell (file->file) - file->start;
|
||||
if (file->sub)
|
||||
file->pos = res;
|
||||
return res;
|
||||
}
|
||||
#ifdef HAVE_ZLIB
|
||||
else {
|
||||
// libz seems to keep track of the true start position itself
|
||||
// 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
|
||||
return -1;
|
||||
|
@ -500,6 +537,8 @@ Qtell (QFile *file)
|
|||
#else
|
||||
return -1;
|
||||
#endif
|
||||
if (file->sub)
|
||||
file->pos = ret;
|
||||
return ret == -1 ? ret : ret - offs;
|
||||
}
|
||||
|
||||
|
@ -521,6 +560,8 @@ Qeof (QFile *file)
|
|||
{
|
||||
if (file->c != -1)
|
||||
return 0;
|
||||
if (file->sub)
|
||||
return file->pos >= file->size;
|
||||
if (file->file)
|
||||
return feof (file->file);
|
||||
#ifdef HAVE_ZLIB
|
||||
|
|
Loading…
Reference in a new issue