# HG changeset patch # User Matti Hamalainen # Date 1353439719 -7200 # Node ID 3c2efa18c4227957e3108bf740ead0cc6003a316 # Parent a5b118c853f541d7e045cda46db5303c5e23c95b Change semantics of xs_fread_be{32,16}() functions to match xs_fread_str() and xs_fread_byte() and change the PSID/RSID file parsing for SLDB MD5 calculation to use them. Also, fix the parser so that PSID/RSID v3 files are supported correctly. diff -r a5b118c853f5 -r 3c2efa18c422 src/xs_length.c --- a/src/xs_length.c Tue Nov 20 21:27:26 2012 +0200 +++ b/src/xs_length.c Tue Nov 20 21:28:39 2012 +0200 @@ -370,67 +370,71 @@ static gint xs_get_sid_hash(const gchar *filename, xs_md5hash_t hash) { - XSFile *inFile; + XSFile *inFile = NULL; xs_md5state_t inState; psidv1_header_t psidH; psidv2_header_t psidH2; - guint8 *songData; + guint8 *songData = NULL; guint8 ib8[2], i8; gint index, result; /* Try to open the file */ if ((inFile = xs_fopen(filename, "rb")) == NULL) - return -1; + goto error; /* Read PSID header in */ - xs_fread(psidH.magicID, sizeof(psidH.magicID), 1, inFile); - if (strncmp(psidH.magicID, "PSID", 4) && - strncmp(psidH.magicID, "RSID", 4)) + if (!xs_fread_str(inFile, psidH.magicID, sizeof(psidH.magicID)) || + !xs_fread_be16(inFile, &psidH.version) || + !xs_fread_be16(inFile, &psidH.dataOffset) || + !xs_fread_be16(inFile, &psidH.loadAddress) || + !xs_fread_be16(inFile, &psidH.initAddress) || + !xs_fread_be16(inFile, &psidH.playAddress) || + !xs_fread_be16(inFile, &psidH.nSongs) || + !xs_fread_be16(inFile, &psidH.startSong) || + !xs_fread_be32(inFile, &psidH.speed)) { - xs_fclose(inFile); - xs_error("Not a PSID or RSID file '%s'\n", filename); - return -2; + xs_error("Could not read PSID/RSID header from '%s'\n", filename); + goto error; } - psidH.version = xs_fread_be16(inFile); - psidH.dataOffset = xs_fread_be16(inFile); - psidH.loadAddress = xs_fread_be16(inFile); - psidH.initAddress = xs_fread_be16(inFile); - psidH.playAddress = xs_fread_be16(inFile); - psidH.nSongs = xs_fread_be16(inFile); - psidH.startSong = xs_fread_be16(inFile); - psidH.speed = xs_fread_be32(inFile); - - xs_fread(psidH.sidName, sizeof(gchar), sizeof(psidH.sidName), inFile); - xs_fread(psidH.sidAuthor, sizeof(gchar), sizeof(psidH.sidAuthor), inFile); - xs_fread(psidH.sidCopyright, sizeof(gchar), sizeof(psidH.sidCopyright), inFile); - - if (xs_feof(inFile) || xs_ferror(inFile)) + if ((strncmp(psidH.magicID, "PSID", 4) && + strncmp(psidH.magicID, "RSID", 4)) || + psidH.version < 1 || psidH.version > 3) { - xs_fclose(inFile); + xs_error("Not a supported PSID or RSID file '%s'\n", filename); + goto error; + } + + if (!xs_fread_str(inFile, psidH.sidName, sizeof(psidH.sidName)) || + !xs_fread_str(inFile, psidH.sidAuthor, sizeof(psidH.sidAuthor)) || + !xs_fread_str(inFile, psidH.sidCopyright, sizeof(psidH.sidCopyright))) + { xs_error("Error reading SID file header from '%s'\n", filename); - return -4; + goto error; } /* Check if we need to load PSIDv2NG header ... */ psidH2.flags = 0; /* Just silence a stupid gcc warning */ - if (psidH.version == 2) + if (psidH.version == 2 || psidH.version == 3) { /* Yes, we need to */ - psidH2.flags = xs_fread_be16(inFile); - psidH2.startPage = xs_fgetc(inFile); - psidH2.pageLength = xs_fgetc(inFile); - psidH2.reserved = xs_fread_be16(inFile); + if (!xs_fread_be16(inFile, &psidH2.flags) || + !xs_fread_byte(inFile, &psidH2.startPage) || + !xs_fread_byte(inFile, &psidH2.startPage) || + !xs_fread_be16(inFile, &psidH2.reserved)) + { + xs_error("Error reading PSID/RSID v2+ extra header data from '%s'\n", + filename); + goto error; + } } /* Allocate buffer */ - songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE * sizeof(guint8)); - if (!songData) + if ((songData = (guint8 *) g_malloc(XS_SIDBUF_SIZE)) == NULL) { - xs_fclose(inFile); xs_error("Error allocating temp data buffer for file '%s'\n", filename); - return -3; + goto error; } /* Read data to buffer */ @@ -479,7 +483,7 @@ xs_md5_append(&inState, &i8, sizeof(i8)); /* PSIDv2NG specific */ - if (psidH.version == 2) + if (psidH.version == 2 || psidH.version == 3) { /* SEE SIDPLAY HEADERS FOR INFO */ i8 = (psidH2.flags >> 2) & 3; @@ -491,6 +495,12 @@ xs_md5_finish(&inState, hash); return 0; + +error: + if (inFile != NULL) + xs_fclose(inFile); + g_free(songData); + return -1; } diff -r a5b118c853f5 -r 3c2efa18c422 src/xs_support.c --- a/src/xs_support.c Tue Nov 20 21:27:26 2012 +0200 +++ b/src/xs_support.c Tue Nov 20 21:28:39 2012 +0200 @@ -116,19 +116,23 @@ } -guint16 xs_fread_be16(XSFile *f) +gboolean xs_fread_be16(XSFile *f, guint16 *val) { - return (((guint16) xs_fgetc(f)) << 8) | ((guint16) xs_fgetc(f)); + guint16 result; + if (xs_fread(&result, sizeof(result), 1, f) != 1) + return FALSE; + *val = GUINT16_FROM_BE(result); + return TRUE; } -guint32 xs_fread_be32(XSFile *f) +gboolean xs_fread_be32(XSFile *f, guint32 *val) { - return - (((guint32) xs_fgetc(f)) << 24) | - (((guint32) xs_fgetc(f)) << 16) | - (((guint32) xs_fgetc(f)) << 8) | - ((guint32) xs_fgetc(f)); + guint32 result; + if (xs_fread(&result, sizeof(result), 1, f) != 1) + return FALSE; + *val = GUINT32_FROM_BE(result); + return TRUE; } diff -r a5b118c853f5 -r 3c2efa18c422 src/xs_support.h --- a/src/xs_support.h Tue Nov 20 21:27:26 2012 +0200 +++ b/src/xs_support.h Tue Nov 20 21:28:39 2012 +0200 @@ -126,10 +126,11 @@ off_t xs_fsize(XSFile *f); #endif -guint16 xs_fread_be16(XSFile *); -guint32 xs_fread_be32(XSFile *); gboolean xs_fread_str(XSFile *, void *, const size_t); gboolean xs_fread_byte(XSFile *, guint8 *); +gboolean xs_fread_be16(XSFile *, guint16 *); +gboolean xs_fread_be32(XSFile *, guint32 *); + gboolean xs_fload_buffer(const gchar *filename, guint8 **pbuf, size_t *bufSize, const size_t maxSize, gboolean failMaxSize); gboolean xs_fload_buffer_path(const gchar *ppath, const gchar *pfilename,