src/file/SDL_rwops.c
changeset 11480 e7a79b236dc0
parent 11416 7e7d8a125d6a
child 11811 5d94cb6b24d3
     1.1 --- a/src/file/SDL_rwops.c	Sat Sep 09 08:34:46 2017 -0700
     1.2 +++ b/src/file/SDL_rwops.c	Sat Sep 09 08:36:37 2017 -0700
     1.3 @@ -32,6 +32,13 @@
     1.4  #include "../core/windows/SDL_windows.h"
     1.5  #endif
     1.6  
     1.7 +#ifdef HAVE_STDIO_H
     1.8 +#include <stdio.h>
     1.9 +#endif
    1.10 +
    1.11 +#ifdef HAVE_LIMITS_H
    1.12 +#include <limits.h>
    1.13 +#endif
    1.14  
    1.15  /* This file provides a general interface for SDL to read and write
    1.16     data sources.  It can easily be extended to files, memory, etc.
    1.17 @@ -306,6 +313,19 @@
    1.18  #define fseek   fseeko64
    1.19  #define ftell   ftello64
    1.20  #elif defined(HAVE_FSEEKO)
    1.21 +#if defined(OFF_MIN) && defined(OFF_MAX)
    1.22 +#define FSEEK_OFF_MIN OFF_MIN
    1.23 +#define FSEEK_OFF_MAX OFF_MAX
    1.24 +#elif defined(HAVE_LIMITS_H)
    1.25 +/* POSIX doesn't specify the minimum and maximum macros for off_t so
    1.26 + * we have to improvise and dance around implementation-defined
    1.27 + * behavior. This may fail if the off_t type has padding bits or
    1.28 + * is not a two's-complement representation. The compilers will detect
    1.29 + * and eliminate the dead code if off_t has 64 bits.
    1.30 + */
    1.31 +#define FSEEK_OFF_MAX (((((off_t)1 << (sizeof(off_t) * CHAR_BIT - 2)) - 1) << 1) + 1)
    1.32 +#define FSEEK_OFF_MIN (-(FSEEK_OFF_MAX) - 1)
    1.33 +#endif
    1.34  #define fseek_off_t off_t
    1.35  #define fseek   fseeko
    1.36  #define ftell   ftello
    1.37 @@ -314,6 +334,10 @@
    1.38  #define fseek   _fseeki64
    1.39  #define ftell   _ftelli64
    1.40  #else
    1.41 +#ifdef HAVE_LIMITS_H
    1.42 +#define FSEEK_OFF_MIN LONG_MIN
    1.43 +#define FSEEK_OFF_MAX LONG_MAX
    1.44 +#endif
    1.45  #define fseek_off_t long
    1.46  #endif
    1.47  
    1.48 @@ -337,8 +361,18 @@
    1.49  static Sint64 SDLCALL
    1.50  stdio_seek(SDL_RWops * context, Sint64 offset, int whence)
    1.51  {
    1.52 +#if defined(FSEEK_OFF_MIN) && defined(FSEEK_OFF_MAX)
    1.53 +    if (offset < (Sint64)(FSEEK_OFF_MIN) || offset > (Sint64)(FSEEK_OFF_MAX)) {
    1.54 +        return SDL_SetError("Seek offset out of range");
    1.55 +    }
    1.56 +#endif
    1.57 +
    1.58      if (fseek(context->hidden.stdio.fp, (fseek_off_t)offset, whence) == 0) {
    1.59 -        return ftell(context->hidden.stdio.fp);
    1.60 +        Sint64 pos = ftell(context->hidden.stdio.fp);
    1.61 +        if (pos < 0) {
    1.62 +            return SDL_SetError("Couldn't get stream offset");
    1.63 +        }
    1.64 +        return pos;
    1.65      }
    1.66      return SDL_Error(SDL_EFSEEK);
    1.67  }