From: <pa...@us...> - 2008-10-21 10:23:06
|
Revision: 3781 http://fuse-emulator.svn.sourceforge.net/fuse-emulator/?rev=3781&view=rev Author: pak21 Date: 2008-10-21 09:45:25 +0000 (Tue, 21 Oct 2008) Log Message: ----------- SP wasn't being decremented and could have been written to freed memory. Modified Paths: -------------- trunk/libspectrum/hacking/ChangeLog trunk/libspectrum/sna.c trunk/libspectrum/test/test.c Added Paths: ----------- trunk/libspectrum/test/empty.z80 Modified: trunk/libspectrum/hacking/ChangeLog =================================================================== --- trunk/libspectrum/hacking/ChangeLog 2008-10-21 09:01:33 UTC (rev 3780) +++ trunk/libspectrum/hacking/ChangeLog 2008-10-21 09:45:25 UTC (rev 3781) @@ -678,3 +678,5 @@ 20080928 internals.h,tape.c,tape_block.[ch],test/test.c: extend timing support to raw data blocks, RLE pulse blocks and the block o' doom (Fred). 20081020 tape_block.c: remove warning. +20081021 sna.c,test/{empty.z80,test.c}: SP wasn't being decremented and + could have been written to freed memory. Modified: trunk/libspectrum/sna.c =================================================================== --- trunk/libspectrum/sna.c 2008-10-21 09:01:33 UTC (rev 3780) +++ trunk/libspectrum/sna.c 2008-10-21 09:45:25 UTC (rev 3781) @@ -32,6 +32,8 @@ #define LIBSPECTRUM_SNA_HEADER_LENGTH 27 #define LIBSPECTRUM_SNA_128_HEADER_LENGTH 4 +#define SNA_OFFSET_SP 23 + static int identify_machine( size_t buffer_length, libspectrum_snap *snap ); static int libspectrum_sna_read_header( const libspectrum_byte *buffer, size_t buffer_length, @@ -48,10 +50,10 @@ static void write_header( libspectrum_byte **buffer, libspectrum_byte **ptr, - size_t *length, libspectrum_byte **sp, libspectrum_snap *snap ); + size_t *length, libspectrum_snap *snap ); static libspectrum_error write_48k_sna( libspectrum_byte **buffer, libspectrum_byte **ptr, - size_t *length, libspectrum_byte *sp, libspectrum_snap *snap ); + size_t *length, libspectrum_snap *snap ); static libspectrum_error write_128k_sna( libspectrum_byte **buffer, libspectrum_byte **ptr, size_t *length, libspectrum_snap *snap ); @@ -287,7 +289,7 @@ int in_flags GCC_UNUSED ) { libspectrum_error error = LIBSPECTRUM_ERROR_NONE; - libspectrum_byte *ptr, *sp; + libspectrum_byte *ptr; /* Minor info loss already due to things like tstate count, halted state, etc which are not stored in .sna format */ @@ -325,7 +327,7 @@ ptr = *buffer; - write_header( buffer, &ptr, length, &sp, snap ); + write_header( buffer, &ptr, length, snap ); switch( libspectrum_snap_machine( snap ) ) { @@ -336,7 +338,7 @@ /* Fall through */ case LIBSPECTRUM_MACHINE_16: case LIBSPECTRUM_MACHINE_48: - error = write_48k_sna( buffer, &ptr, length, sp, snap ); + error = write_48k_sna( buffer, &ptr, length, snap ); break; case LIBSPECTRUM_MACHINE_128: @@ -370,7 +372,7 @@ static void write_header( libspectrum_byte **buffer, libspectrum_byte **ptr, - size_t *length, libspectrum_byte **sp, libspectrum_snap *snap ) + size_t *length, libspectrum_snap *snap ) { libspectrum_make_room( buffer, LIBSPECTRUM_SNA_HEADER_LENGTH, ptr, length ); @@ -392,8 +394,6 @@ *(*ptr)++ = libspectrum_snap_f ( snap ); *(*ptr)++ = libspectrum_snap_a ( snap ); - /* Store this for later */ - *sp = *ptr; libspectrum_write_word( ptr, libspectrum_snap_sp ( snap ) ); *(*ptr)++ = libspectrum_snap_im( snap ); @@ -402,15 +402,15 @@ static libspectrum_error write_48k_sna( libspectrum_byte **buffer, libspectrum_byte **ptr, - size_t *length, libspectrum_byte *sp, libspectrum_snap *snap ) + size_t *length, libspectrum_snap *snap ) { libspectrum_error error; - libspectrum_byte *stack; + libspectrum_byte *stack, *sp; - /* Must have somewhere in RAM to store some registers */ + /* Must have somewhere in RAM to store PC */ if( libspectrum_snap_sp( snap ) < 0x4002 ) { libspectrum_print_error( LIBSPECTRUM_ERROR_INVALID, - "SP is too low (0x%04x) to stack registers", + "SP is too low (0x%04x) to stack PC", libspectrum_snap_sp( snap ) ); return LIBSPECTRUM_ERROR_INVALID; } @@ -431,7 +431,8 @@ *ptr += 0xc000; /* Store the new value of SP */ - libspectrum_write_word( &sp, libspectrum_snap_sp( snap ) ); + sp = *buffer + SNA_OFFSET_SP; + libspectrum_write_word( &sp, libspectrum_snap_sp( snap ) - 2 ); return LIBSPECTRUM_ERROR_NONE; } Added: trunk/libspectrum/test/empty.z80 =================================================================== (Binary files differ) Property changes on: trunk/libspectrum/test/empty.z80 ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/libspectrum/test/test.c =================================================================== --- trunk/libspectrum/test/test.c 2008-10-21 09:01:33 UTC (rev 3780) +++ trunk/libspectrum/test/test.c 2008-10-21 09:45:25 UTC (rev 3781) @@ -562,6 +562,69 @@ return r; } +static test_return_t +test_25( void ) +{ + const char *filename = STATIC_TEST_PATH( "empty.z80" ); + libspectrum_byte *buffer = NULL; + size_t filesize = 0, length = 0; + libspectrum_snap *snap; + int flags; + test_return_t r = TEST_INCOMPLETE; + + if( read_file( &buffer, &filesize, filename ) ) return TEST_INCOMPLETE; + + snap = libspectrum_snap_alloc(); + + if( libspectrum_snap_read( snap, buffer, filesize, LIBSPECTRUM_ID_UNKNOWN, + filename ) != LIBSPECTRUM_ERROR_NONE ) { + fprintf( stderr, "%s: reading `%s' failed\n", progname, filename ); + libspectrum_snap_free( snap ); + libspectrum_free( buffer ); + return TEST_INCOMPLETE; + } + + libspectrum_free( buffer ); + buffer = NULL; + + if( libspectrum_snap_write( &buffer, &length, &flags, snap, + LIBSPECTRUM_ID_SNAPSHOT_SNA, NULL, 0 ) != + LIBSPECTRUM_ERROR_NONE ) { + fprintf( stderr, "%s: serialising to SNA failed\n", progname ); + libspectrum_snap_free( snap ); + return TEST_INCOMPLETE; + } + + libspectrum_snap_free( snap ); + snap = libspectrum_snap_alloc(); + + if( libspectrum_snap_read( snap, buffer, length, LIBSPECTRUM_ID_SNAPSHOT_SNA, + NULL ) != LIBSPECTRUM_ERROR_NONE ) { + fprintf( stderr, "%s: restoring from SNA failed\n", progname ); + libspectrum_snap_free( snap ); + libspectrum_free( buffer ); + return TEST_INCOMPLETE; + } + + libspectrum_free( buffer ); + + if( libspectrum_snap_pc( snap ) != 0x1234 ) { + fprintf( stderr, "%s: PC is 0x%04x, not the expected 0x1234\n", progname, + libspectrum_snap_pc( snap ) ); + r = TEST_FAIL; + } else if( libspectrum_snap_sp( snap ) != 0x8000 ) { + fprintf( stderr, "%s: SP is 0x%04x, not the expected 0x8000\n", progname, + libspectrum_snap_sp( snap ) ); + r = TEST_FAIL; + } else { + r = TEST_PASS; + } + + libspectrum_snap_free( snap ); + + return r; +} + struct test_description { test_fn test; @@ -595,6 +658,7 @@ { test_22, "MDR write protection 1", 0 }, { test_23, "MDR write protection 2", 0 }, { test_24, "Complete TZX timings", 0 }, + { test_25, "Writing SNA file", 0 }, }; static size_t test_count = sizeof( tests ) / sizeof( tests[0] ); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |