Fix bug 122 - SDL_RWops bug fixes: set RWops.type field, add input validation, add test coverage
authorAndreas Schiffler <aschiffler@ferzkopp.net>
Wed, 13 Mar 2013 08:35:03 -0700
changeset 6999681820ca0e78
parent 6998 f7faeaa02efb
child 7000 1afa71309a0e
Fix bug 122 - SDL_RWops bug fixes: set RWops.type field, add input validation, add test coverage
include/SDL_rwops.h
src/file/SDL_rwops.c
test/testautomation_rwops.c
     1.1 --- a/include/SDL_rwops.h	Tue Mar 12 18:28:40 2013 -0700
     1.2 +++ b/include/SDL_rwops.h	Wed Mar 13 08:35:03 2013 -0700
     1.3 @@ -40,6 +40,14 @@
     1.4  /* *INDENT-ON* */
     1.5  #endif
     1.6  
     1.7 +/* RWops Types */
     1.8 +#define SDL_RWOPS_UNKNOWN	0	/* Unknown stream type */
     1.9 +#define SDL_RWOPS_WINFILE	1	/* Win32 file */
    1.10 +#define SDL_RWOPS_STDFILE	2	/* Stdio file */
    1.11 +#define SDL_RWOPS_JNIFILE	3	/* Android asset */
    1.12 +#define SDL_RWOPS_MEMORY	4	/* Memory stream */
    1.13 +#define SDL_RWOPS_MEMORY_RO	5	/* Read-Only memory stream */
    1.14 +
    1.15  /**
    1.16   * This is the read/write operation structure -- very basic.
    1.17   */
     2.1 --- a/src/file/SDL_rwops.c	Tue Mar 12 18:28:40 2013 -0700
     2.2 +++ b/src/file/SDL_rwops.c	Wed Mar 13 08:35:03 2013 -0700
     2.3 @@ -513,6 +513,7 @@
     2.4      rwops->read = Android_JNI_FileRead;
     2.5      rwops->write = Android_JNI_FileWrite;
     2.6      rwops->close = Android_JNI_FileClose;
     2.7 +    rwops->type = SDL_RWOPS_JNIFILE;
     2.8  
     2.9  #elif defined(__WIN32__)
    2.10      rwops = SDL_AllocRW();
    2.11 @@ -527,6 +528,7 @@
    2.12      rwops->read = windows_file_read;
    2.13      rwops->write = windows_file_write;
    2.14      rwops->close = windows_file_close;
    2.15 +    rwops->type = SDL_RWOPS_WINFILE;
    2.16  
    2.17  #elif HAVE_STDIO_H
    2.18      {
    2.19 @@ -570,6 +572,7 @@
    2.20          rwops->close = stdio_close;
    2.21          rwops->hidden.stdio.fp = fp;
    2.22          rwops->hidden.stdio.autoclose = autoclose;
    2.23 +        rwops->type = SDL_RWOPS_STDFILE;
    2.24      }
    2.25      return (rwops);
    2.26  }
    2.27 @@ -585,7 +588,15 @@
    2.28  SDL_RWops *
    2.29  SDL_RWFromMem(void *mem, int size)
    2.30  {
    2.31 -    SDL_RWops *rwops;
    2.32 +    SDL_RWops *rwops = NULL;
    2.33 +    if (!mem) {
    2.34 +      SDL_InvalidParamError("mem");
    2.35 +      return (rwops);
    2.36 +    }
    2.37 +    if (!size) {
    2.38 +      SDL_InvalidParamError("size");
    2.39 +      return (rwops);
    2.40 +    }
    2.41  
    2.42      rwops = SDL_AllocRW();
    2.43      if (rwops != NULL) {
    2.44 @@ -597,6 +608,7 @@
    2.45          rwops->hidden.mem.base = (Uint8 *) mem;
    2.46          rwops->hidden.mem.here = rwops->hidden.mem.base;
    2.47          rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
    2.48 +        rwops->type = SDL_RWOPS_MEMORY;
    2.49      }
    2.50      return (rwops);
    2.51  }
    2.52 @@ -604,7 +616,15 @@
    2.53  SDL_RWops *
    2.54  SDL_RWFromConstMem(const void *mem, int size)
    2.55  {
    2.56 -    SDL_RWops *rwops;
    2.57 +    SDL_RWops *rwops = NULL;
    2.58 +    if (!mem) {
    2.59 +      SDL_InvalidParamError("mem");
    2.60 +      return (rwops);
    2.61 +    }
    2.62 +    if (!size) {
    2.63 +      SDL_InvalidParamError("size");
    2.64 +      return (rwops);
    2.65 +    }
    2.66  
    2.67      rwops = SDL_AllocRW();
    2.68      if (rwops != NULL) {
    2.69 @@ -616,6 +636,7 @@
    2.70          rwops->hidden.mem.base = (Uint8 *) mem;
    2.71          rwops->hidden.mem.here = rwops->hidden.mem.base;
    2.72          rwops->hidden.mem.stop = rwops->hidden.mem.base + size;
    2.73 +        rwops->type = SDL_RWOPS_MEMORY_RO;
    2.74      }
    2.75      return (rwops);
    2.76  }
    2.77 @@ -629,6 +650,7 @@
    2.78      if (area == NULL) {
    2.79          SDL_OutOfMemory();
    2.80      }
    2.81 +    area->type = SDL_RWOPS_UNKNOWN;
    2.82      return (area);
    2.83  }
    2.84  
     3.1 --- a/test/testautomation_rwops.c	Tue Mar 12 18:28:40 2013 -0700
     3.2 +++ b/test/testautomation_rwops.c	Wed Mar 13 08:35:03 2013 -0700
     3.3 @@ -21,16 +21,18 @@
     3.4  
     3.5  const char* RWopsReadTestFilename = "rwops_read";
     3.6  const char* RWopsWriteTestFilename = "rwops_write";
     3.7 +const char* RWopsAlphabetFilename = "rwops_alphabet";
     3.8  
     3.9  static const char RWopsHelloWorldTestString[] = "Hello World!";
    3.10  static const char RWopsHelloWorldCompString[] = "Hello World!";
    3.11 +static const char RWopsAlphabetString[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    3.12  
    3.13  /* Fixture */
    3.14  
    3.15  void
    3.16  RWopsSetUp(void *arg)
    3.17  {
    3.18 -	int fileLen = SDL_strlen(RWopsHelloWorldTestString);
    3.19 +	int fileLen;
    3.20  	FILE *handle;
    3.21  	int writtenLen;
    3.22  	int result;
    3.23 @@ -38,18 +40,32 @@
    3.24  	/* Clean up from previous runs (if any); ignore errors */
    3.25  	remove(RWopsReadTestFilename);
    3.26  	remove(RWopsWriteTestFilename);
    3.27 +	remove(RWopsAlphabetFilename);
    3.28  
    3.29  	/* Create a test file */
    3.30  	handle = fopen(RWopsReadTestFilename, "w");
    3.31  	SDLTest_AssertCheck(handle != NULL, "Verify creation of file '%s' returned non NULL handle", RWopsReadTestFilename);
    3.32          if (handle == NULL) return;
    3.33  
    3.34 -	/* Write some known test into it */
    3.35 +	/* Write some known text into it */
    3.36 +	fileLen = SDL_strlen(RWopsHelloWorldTestString);
    3.37  	writtenLen = (int)fwrite(RWopsHelloWorldTestString, 1, fileLen, handle);
    3.38  	SDLTest_AssertCheck(fileLen == writtenLen, "Verify number of written bytes, expected %i, got %i", fileLen, writtenLen);
    3.39  	result = fclose(handle);
    3.40  	SDLTest_AssertCheck(result == 0, "Verify result from fclose, expected 0, got %i", result);
    3.41  
    3.42 +	/* Create a second test file */
    3.43 +	handle = fopen(RWopsAlphabetFilename, "w");
    3.44 +	SDLTest_AssertCheck(handle != NULL, "Verify creation of file '%s' returned non NULL handle", RWopsAlphabetFilename);
    3.45 +        if (handle == NULL) return;
    3.46 +
    3.47 +	/* Write alphabet text into it */
    3.48 +	fileLen = SDL_strlen(RWopsAlphabetString);
    3.49 +	writtenLen = (int)fwrite(RWopsAlphabetString, 1, fileLen, handle);
    3.50 +	SDLTest_AssertCheck(fileLen == writtenLen, "Verify number of written bytes, expected %i, got %i", fileLen, writtenLen);
    3.51 +	result = fclose(handle);
    3.52 +	SDLTest_AssertCheck(result == 0, "Verify result from fclose, expected 0, got %i", result);
    3.53 +
    3.54  	SDLTest_AssertPass("Creation of test file completed");
    3.55  }
    3.56  
    3.57 @@ -62,6 +78,8 @@
    3.58  	result = remove(RWopsReadTestFilename);
    3.59  	SDLTest_AssertCheck(result == 0, "Verify result from remove(%s), expected 0, got %i", RWopsReadTestFilename, result);
    3.60  	remove(RWopsWriteTestFilename);
    3.61 +	result = remove(RWopsAlphabetFilename);
    3.62 +	SDLTest_AssertCheck(result == 0, "Verify result from remove(%s), expected 0, got %i", RWopsAlphabetFilename, result);
    3.63  
    3.64  	SDLTest_AssertPass("Cleanup of test files completed");
    3.65  }
    3.66 @@ -137,6 +155,14 @@
    3.67  	   "Verify seek to -1 with SDL_RWseek (RW_SEEK_END), expected %i, got %i",
    3.68  	   sizeof(RWopsHelloWorldTestString)-2,
    3.69  	   i);
    3.70 +	   
    3.71 +   /* Invalid whence seek */
    3.72 +   i = SDL_RWseek( rw, 0, 999 );
    3.73 +   SDLTest_AssertPass("Call to SDL_RWseek(...,0,invalid_whence) succeeded");
    3.74 +   SDLTest_AssertCheck(
    3.75 +	   i == (Sint64)(-1), 
    3.76 +	   "Verify seek with SDL_RWseek (invalid_whence); expected: -1, got %i",
    3.77 +	   i);
    3.78  }
    3.79  
    3.80  /*!
    3.81 @@ -171,6 +197,18 @@
    3.82     SDLTest_AssertPass("Call to SDL_RWFromFile(\"something\", NULL) succeeded");
    3.83     SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromFile(\"something\", NULL) returns NULL");
    3.84  
    3.85 +   rwops = SDL_RWFromMem((void *)NULL, 10);
    3.86 +   SDLTest_AssertPass("Call to SDL_RWFromMem(NULL, 10) succeeded");
    3.87 +   SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromMem(NULL, 10) returns NULL");
    3.88 +
    3.89 +   rwops = SDL_RWFromMem((void *)RWopsAlphabetString, 0);
    3.90 +   SDLTest_AssertPass("Call to SDL_RWFromMem(data, 0) succeeded");
    3.91 +   SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromMem(data, 0) returns NULL");
    3.92 +
    3.93 +   rwops = SDL_RWFromConstMem((const void *)RWopsAlphabetString, 0);
    3.94 +   SDLTest_AssertPass("Call to SDL_RWFromConstMem(data, 0) succeeded");
    3.95 +   SDLTest_AssertCheck(rwops == NULL, "Verify SDL_RWFromConstMem(data, 0) returns NULL");
    3.96 +
    3.97     return TEST_COMPLETED;
    3.98  }
    3.99  
   3.100 @@ -178,13 +216,14 @@
   3.101   * @brief Tests opening from memory.
   3.102   *
   3.103   * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromMem
   3.104 - * http://wiki.libsdl.org/moin.cgi/SDL_RWClose
   3.105 + * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWClose
   3.106   */
   3.107  int
   3.108  rwops_testMem (void)
   3.109  {
   3.110     char mem[sizeof(RWopsHelloWorldTestString)];
   3.111     SDL_RWops *rw;
   3.112 +   int result;
   3.113  
   3.114     /* Clear buffer */
   3.115     SDL_zero(mem);
   3.116 @@ -197,12 +236,16 @@
   3.117     /* Bail out if NULL */
   3.118     if (rw == NULL) return TEST_ABORTED;
   3.119  
   3.120 +   /* Check type */
   3.121 +   SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY, "Verify RWops type is SDL_RWOPS_MEMORY; expected: %d, got: %d", SDL_RWOPS_MEMORY, rw->type);
   3.122 +
   3.123     /* Run generic tests */
   3.124     _testGenericRWopsValidations(rw, 1);
   3.125  
   3.126     /* Close */
   3.127 -   SDL_RWclose(rw);
   3.128 +   result = SDL_RWclose(rw);
   3.129     SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
   3.130 +   SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.131  
   3.132     return TEST_COMPLETED;
   3.133  }
   3.134 @@ -219,6 +262,7 @@
   3.135  rwops_testConstMem (void)
   3.136  {
   3.137     SDL_RWops *rw;
   3.138 +   int result;
   3.139  
   3.140     /* Open handle */
   3.141     rw = SDL_RWFromConstMem( RWopsHelloWorldCompString, sizeof(RWopsHelloWorldCompString)-1 );
   3.142 @@ -228,12 +272,16 @@
   3.143     /* Bail out if NULL */
   3.144     if (rw == NULL) return TEST_ABORTED;
   3.145  
   3.146 +   /* Check type */
   3.147 +   SDLTest_AssertCheck(rw->type == SDL_RWOPS_MEMORY_RO, "Verify RWops type is SDL_RWOPS_MEMORY_RO; expected: %d, got: %d", SDL_RWOPS_MEMORY_RO, rw->type);
   3.148 +
   3.149     /* Run generic tests */
   3.150     _testGenericRWopsValidations( rw, 0 );
   3.151  
   3.152     /* Close handle */
   3.153 -   SDL_RWclose(rw);
   3.154 +   result = SDL_RWclose(rw);
   3.155     SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
   3.156 +   SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.157  
   3.158    return TEST_COMPLETED;
   3.159  }
   3.160 @@ -250,6 +298,7 @@
   3.161  rwops_testFileRead(void)
   3.162  {
   3.163     SDL_RWops *rw;
   3.164 +   int result;
   3.165  
   3.166     /* Read test. */
   3.167     rw = SDL_RWFromFile(RWopsReadTestFilename, "r");
   3.168 @@ -259,12 +308,28 @@
   3.169     // Bail out if NULL
   3.170     if (rw == NULL) return TEST_ABORTED;
   3.171  
   3.172 +   /* Check type */
   3.173 +#if defined(ANDROID)
   3.174 +   SDLTest_AssertCheck(
   3.175 +      rw->type == SDL_RWOPS_STDFILE || rw->type == SDL_RWOPS_JNIFILE, 
   3.176 +      "Verify RWops type is SDL_RWOPS_STDFILE or SDL_RWOPS_JNIFILE; expected: %d|%d, got: %d", SDL_RWOPS_STDFILE, SDL_RWOPS_JNIFILE, rw->type);
   3.177 +#elif defined(__WIN32__)
   3.178 +   SDLTest_AssertCheck(
   3.179 +      rw->type == SDL_RWOPS_WINFILE, 
   3.180 +      "Verify RWops type is SDL_RWOPS_WINFILE; expected: %d, got: %d", SDL_RWOPS_WINFILE, rw->type);
   3.181 +#else
   3.182 +   SDLTest_AssertCheck(
   3.183 +      rw->type == SDL_RWOPS_STDFILE, 
   3.184 +      "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type);
   3.185 +#endif
   3.186 +
   3.187     /* Run generic tests */
   3.188     _testGenericRWopsValidations( rw, 0 );
   3.189  
   3.190     /* Close handle */
   3.191 -   SDL_RWclose(rw);
   3.192 +   result = SDL_RWclose(rw);
   3.193     SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
   3.194 +   SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.195  
   3.196     return TEST_COMPLETED;
   3.197  }
   3.198 @@ -280,6 +345,7 @@
   3.199  rwops_testFileWrite(void)
   3.200  {
   3.201     SDL_RWops *rw;
   3.202 +   int result;
   3.203  
   3.204     /* Write test. */
   3.205     rw = SDL_RWFromFile(RWopsWriteTestFilename, "w+");
   3.206 @@ -289,12 +355,28 @@
   3.207     // Bail out if NULL
   3.208     if (rw == NULL) return TEST_ABORTED;
   3.209  
   3.210 +   /* Check type */
   3.211 +#if defined(ANDROID)
   3.212 +   SDLTest_AssertCheck(
   3.213 +      rw->type == SDL_RWOPS_STDFILE || rw->type == SDL_RWOPS_JNIFILE, 
   3.214 +      "Verify RWops type is SDL_RWOPS_STDFILE or SDL_RWOPS_JNIFILE; expected: %d|%d, got: %d", SDL_RWOPS_STDFILE, SDL_RWOPS_JNIFILE, rw->type);
   3.215 +#elif defined(__WIN32__)
   3.216 +   SDLTest_AssertCheck(
   3.217 +      rw->type == SDL_RWOPS_WINFILE, 
   3.218 +      "Verify RWops type is SDL_RWOPS_WINFILE; expected: %d, got: %d", SDL_RWOPS_WINFILE, rw->type);
   3.219 +#else
   3.220 +   SDLTest_AssertCheck(
   3.221 +      rw->type == SDL_RWOPS_STDFILE, 
   3.222 +      "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type);
   3.223 +#endif
   3.224 +
   3.225     /* Run generic tests */
   3.226     _testGenericRWopsValidations( rw, 1 );
   3.227  
   3.228     /* Close handle */
   3.229 -   SDL_RWclose(rw);
   3.230 +   result = SDL_RWclose(rw);
   3.231     SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
   3.232 +   SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.233  
   3.234     return TEST_COMPLETED;
   3.235  }
   3.236 @@ -313,6 +395,7 @@
   3.237  {
   3.238     FILE *fp;
   3.239     SDL_RWops *rw;
   3.240 +   int result;
   3.241  
   3.242     /* Run read tests. */
   3.243     fp = fopen(RWopsReadTestFilename, "r");
   3.244 @@ -332,12 +415,18 @@
   3.245       return TEST_ABORTED;
   3.246     }
   3.247  
   3.248 +   /* Check type */
   3.249 +   SDLTest_AssertCheck(
   3.250 +      rw->type == SDL_RWOPS_STDFILE, 
   3.251 +      "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type);
   3.252 +
   3.253     /* Run generic tests */
   3.254     _testGenericRWopsValidations( rw, 0 );
   3.255  
   3.256     /* Close handle - does fclose() */
   3.257 -   SDL_RWclose(rw);
   3.258 +   result = SDL_RWclose(rw);
   3.259     SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
   3.260 +   SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.261  
   3.262     return TEST_COMPLETED;
   3.263  }
   3.264 @@ -356,6 +445,7 @@
   3.265  {
   3.266     FILE *fp;
   3.267     SDL_RWops *rw;
   3.268 +   int result;
   3.269  
   3.270     /* Run write tests. */
   3.271     fp = fopen(RWopsWriteTestFilename, "w+");
   3.272 @@ -375,12 +465,18 @@
   3.273       return TEST_ABORTED;
   3.274     }
   3.275  
   3.276 +   /* Check type */
   3.277 +   SDLTest_AssertCheck(
   3.278 +      rw->type == SDL_RWOPS_STDFILE, 
   3.279 +      "Verify RWops type is SDL_RWOPS_STDFILE; expected: %d, got: %d", SDL_RWOPS_STDFILE, rw->type);
   3.280 +
   3.281     /* Run generic tests */
   3.282     _testGenericRWopsValidations( rw, 1 );
   3.283  
   3.284     /* Close handle - does fclose() */
   3.285 -   SDL_RWclose(rw);
   3.286 +   result = SDL_RWclose(rw);
   3.287     SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
   3.288 +   SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.289  
   3.290     return TEST_COMPLETED;
   3.291  }
   3.292 @@ -399,6 +495,11 @@
   3.293     SDLTest_AssertPass("Call to SDL_AllocRW() succeeded");
   3.294     SDLTest_AssertCheck(rw != NULL, "Validate result from SDL_AllocRW() is not NULL");
   3.295     if (rw==NULL) return TEST_ABORTED;
   3.296 +
   3.297 +   /* Check type */
   3.298 +   SDLTest_AssertCheck(
   3.299 +      rw->type == SDL_RWOPS_UNKNOWN, 
   3.300 +      "Verify RWops type is SDL_RWOPS_UNKNOWN; expected: %d, got: %d", SDL_RWOPS_UNKNOWN, rw->type);
   3.301            
   3.302     /* Free context again */
   3.303     SDL_FreeRW(rw);
   3.304 @@ -408,6 +509,72 @@
   3.305  }
   3.306  
   3.307  /**
   3.308 + * @brief Compare memory and file reads
   3.309 + *
   3.310 + * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromMem
   3.311 + * \sa http://wiki.libsdl.org/moin.cgi/SDL_RWFromFile
   3.312 + */
   3.313 +int
   3.314 +rwops_testCompareRWFromMemWithRWFromFile(void)
   3.315 +{
   3.316 +   int slen = 26;
   3.317 +   char buffer_file[27];
   3.318 +   char buffer_mem[27];
   3.319 +   size_t rv_file;
   3.320 +   size_t rv_mem;
   3.321 +   Uint64 sv_file;
   3.322 +   Uint64 sv_mem;
   3.323 +   SDL_RWops* rwops_file;
   3.324 +   SDL_RWops* rwops_mem;
   3.325 +   int size;
   3.326 +   int result;
   3.327 +
   3.328 +   
   3.329 +   for (size=5; size<10; size++)
   3.330 +   {
   3.331 +     /* Terminate buffer */
   3.332 +     buffer_file[slen] = 0;
   3.333 +     buffer_mem[slen] = 0;
   3.334 +     
   3.335 +     /* Read/seek from memory */
   3.336 +     rwops_mem = SDL_RWFromMem((void *)RWopsAlphabetString, slen);
   3.337 +     SDLTest_AssertPass("Call to SDL_RWFromMem()");
   3.338 +     rv_mem = SDL_RWread(rwops_mem, buffer_mem, size, 6);
   3.339 +     SDLTest_AssertPass("Call to SDL_RWread(mem, size=%d)", size);
   3.340 +     sv_mem = SDL_RWseek(rwops_mem, 0, SEEK_END);
   3.341 +     SDLTest_AssertPass("Call to SDL_RWseek(mem,SEEK_END)");
   3.342 +     result = SDL_RWclose(rwops_mem);
   3.343 +     SDLTest_AssertPass("Call to SDL_RWclose(mem)");
   3.344 +     SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.345 +
   3.346 +     /* Read/see from file */
   3.347 +     rwops_file = SDL_RWFromFile(RWopsAlphabetFilename, "r");
   3.348 +     SDLTest_AssertPass("Call to SDL_RWFromFile()");
   3.349 +     rv_file = SDL_RWread(rwops_file, buffer_file, size, 6);
   3.350 +     SDLTest_AssertPass("Call to SDL_RWread(file, size=%d)", size);
   3.351 +     sv_file = SDL_RWseek(rwops_file, 0, SEEK_END);
   3.352 +     SDLTest_AssertPass("Call to SDL_RWseek(file,SEEK_END)");
   3.353 +     result = SDL_RWclose(rwops_file);
   3.354 +     SDLTest_AssertPass("Call to SDL_RWclose(file)");
   3.355 +     SDLTest_AssertCheck(result == 0, "Verify result value is 0; got: %d", result);
   3.356 +   
   3.357 +     /* Compare */
   3.358 +     SDLTest_AssertCheck(rv_mem == rv_file, "Verify returned read blocks matches for mem and file reads; got: rv_mem=%d rv_file=%d", rv_mem, rv_file);
   3.359 +     SDLTest_AssertCheck(sv_mem == sv_file, "Verify SEEK_END position matches for mem and file seeks; got: sv_mem=%llu sv_file=%llu", sv_mem, sv_file);
   3.360 +     SDLTest_AssertCheck(buffer_mem[slen] == 0, "Verify mem buffer termination; expected: 0, got: %d", buffer_mem[slen]);
   3.361 +     SDLTest_AssertCheck(buffer_file[slen] == 0, "Verify file buffer termination; expected: 0, got: %d", buffer_file[slen]);
   3.362 +     SDLTest_AssertCheck(
   3.363 +       SDL_strncmp(buffer_mem, RWopsAlphabetString, slen) == 0,
   3.364 +       "Verify mem buffer contain alphabet string; expected: %s, got: %s", RWopsAlphabetString, buffer_mem);
   3.365 +     SDLTest_AssertCheck(
   3.366 +       SDL_strncmp(buffer_file, RWopsAlphabetString, slen) == 0,
   3.367 +       "Verify file buffer contain alphabet string; expected: %s, got: %s", RWopsAlphabetString, buffer_file);
   3.368 +   }
   3.369 +      
   3.370 +   return TEST_COMPLETED;
   3.371 +}
   3.372 +
   3.373 +/**
   3.374   * @brief Tests writing and reading from file using endian aware functions.
   3.375   *
   3.376   * \sa
   3.377 @@ -435,6 +602,7 @@
   3.378     Uint16 LE16test;
   3.379     Uint32 LE32test;
   3.380     Uint64 LE64test;
   3.381 +   int cresult;
   3.382  
   3.383     for (mode = 0; mode < 3; mode++) {
   3.384     
   3.385 @@ -523,9 +691,9 @@
   3.386       SDLTest_AssertCheck(LE64test == LE64value, "Validate return value from SDL_ReadLE64, expected: %llu, got: %llu", LE64value, LE64test);
   3.387  
   3.388       /* Close handle */
   3.389 -     SDL_RWclose(rw);
   3.390 +     cresult = SDL_RWclose(rw);
   3.391       SDLTest_AssertPass("Call to SDL_RWclose() succeeded");
   3.392 -   
   3.393 +     SDLTest_AssertCheck(cresult == 0, "Verify result value is 0; got: %d", cresult);   
   3.394     }
   3.395  
   3.396     return TEST_COMPLETED;
   3.397 @@ -562,10 +730,13 @@
   3.398  static const SDLTest_TestCaseReference rwopsTest9 =
   3.399  		{ (SDLTest_TestCaseFp)rwops_testFileWriteReadEndian, "rwops_testFileWriteReadEndian", "Test writing and reading via the Endian aware functions", TEST_ENABLED };
   3.400  
   3.401 +static const SDLTest_TestCaseReference rwopsTest10 =
   3.402 +		{ (SDLTest_TestCaseFp)rwops_testCompareRWFromMemWithRWFromFile, "rwops_testCompareRWFromMemWithRWFromFile", "Compare RWFromMem and RWFromFile RWops for read and seek", TEST_ENABLED };
   3.403 +
   3.404  /* Sequence of RWops test cases */
   3.405  static const SDLTest_TestCaseReference *rwopsTests[] =  {
   3.406  	&rwopsTest1, &rwopsTest2, &rwopsTest3, &rwopsTest4, &rwopsTest5, &rwopsTest6, 
   3.407 -	&rwopsTest7, &rwopsTest8, &rwopsTest9, NULL
   3.408 +	&rwopsTest7, &rwopsTest8, &rwopsTest9, &rwopsTest10, NULL
   3.409  };
   3.410  
   3.411  /* RWops test suite (global) */