From d44f61b583a112e23a9af405968b11514979fedf Mon Sep 17 00:00:00 2001
From: Lars-Dominik Braun <lars@6xq.net>
Date: Sun, 15 Jan 2012 20:21:50 +0100
Subject: piano: Make sync response parser NUL-byte aware

Fixes #207
---
 src/libpiano/crypt.c | 13 ++++++++++---
 src/libpiano/crypt.h |  4 ++--
 src/libpiano/piano.c | 27 +++++++++++++--------------
 src/libpiano/xml.c   |  2 +-
 4 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/src/libpiano/crypt.c b/src/libpiano/crypt.c
index e833868..3f98f42 100644
--- a/src/libpiano/crypt.c
+++ b/src/libpiano/crypt.c
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2008-2010
+Copyright (c) 2008-2011
 	Lars-Dominik Braun <lars@6xq.net>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -43,20 +43,23 @@ THE SOFTWARE.
 /*	decrypt hex-encoded, blowfish-crypted string: decode 2 hex-encoded blocks,
  *	decrypt, byteswap
  *	@param hex string
+ *	@param decrypted string length (without trailing NUL)
  *	@return decrypted string or NULL
  */
 #define INITIAL_SHIFT 28
 #define SHIFT_DEC 4
-char *PianoDecryptString (const char * const s) {
+char *PianoDecryptString (const char * const s, size_t * const retSize) {
 	const unsigned char *strInput = (const unsigned char *) s;
 	/* hex-decode => strlen/2 + null-byte */
 	uint32_t *iDecrypt;
+	size_t decryptedSize;
 	char *strDecrypted;
 	unsigned char shift = INITIAL_SHIFT, intsDecoded = 0, j;
 	/* blowfish blocks, 32-bit */
 	uint32_t f, l, r, lrExchange;
 
-	if ((iDecrypt = calloc (strlen ((const char *) strInput)/2/sizeof (*iDecrypt)+1,
+	decryptedSize = strlen ((const char *) strInput)/2;
+	if ((iDecrypt = calloc (decryptedSize/sizeof (*iDecrypt)+1,
 			sizeof (*iDecrypt))) == NULL) {
 		return NULL;
 	}
@@ -112,6 +115,10 @@ char *PianoDecryptString (const char * const s) {
 		++strInput;
 	}
 
+	if (retSize != NULL) {
+		*retSize = decryptedSize;
+	}
+
 	return strDecrypted;
 }
 #undef INITIAL_SHIFT
diff --git a/src/libpiano/crypt.h b/src/libpiano/crypt.h
index 6b2fb96..945e9e6 100644
--- a/src/libpiano/crypt.h
+++ b/src/libpiano/crypt.h
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2008-2010
+Copyright (c) 2008-2011
 	Lars-Dominik Braun <lars@6xq.net>
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -24,7 +24,7 @@ THE SOFTWARE.
 #ifndef _CRYPH_H
 #define _CRYPT_H
 
-char *PianoDecryptString (const char *strInput);
+char *PianoDecryptString (const char * const, size_t * const);
 char *PianoEncryptString (const char *strInput);
 
 #endif /* _CRYPT_H */
diff --git a/src/libpiano/piano.c b/src/libpiano/piano.c
index 3a5e97c..2c2a8d8 100644
--- a/src/libpiano/piano.c
+++ b/src/libpiano/piano.c
@@ -900,24 +900,23 @@ PianoReturn_t PianoResponse (PianoHandle_t *ph, PianoRequest_t *req) {
 
 					/* abusing parseNarrative; has same xml structure */
 					ret = PianoXmlParseNarrative (req->responseData, &cryptedTimestamp);
-					if (cryptedTimestamp != NULL) {
+					if (ret == PIANO_RET_OK && cryptedTimestamp != NULL) {
 						unsigned long timestamp = 0;
-						time_t realTimestamp = time (NULL);
-						char *decryptedTimestamp = NULL, *decryptedPos = NULL;
-						unsigned char i = 4;
-
-						if ((decryptedTimestamp = PianoDecryptString (cryptedTimestamp)) != NULL) {
-							decryptedPos = decryptedTimestamp;
-							/* skip four bytes garbage? at beginning */
-							while (i-- > 0 && *decryptedPos++ != '\0');
-							timestamp = strtoul (decryptedPos, NULL, 0);
+						const time_t realTimestamp = time (NULL);
+						char *decryptedTimestamp = NULL;
+						size_t decryptedSize;
+
+						ret = PIANO_RET_ERR;
+						if ((decryptedTimestamp = PianoDecryptString (cryptedTimestamp,
+								&decryptedSize)) != NULL && decryptedSize > 4) {
+							/* skip four bytes garbage(?) at beginning */
+							timestamp = strtoul (decryptedTimestamp+4, NULL, 0);
 							ph->timeOffset = realTimestamp - timestamp;
-
-							free (decryptedTimestamp);
+							ret = PIANO_RET_CONTINUE_REQUEST;
 						}
-						free (cryptedTimestamp);
+						free (decryptedTimestamp);
 					}
-					ret = PIANO_RET_CONTINUE_REQUEST;
+					free (cryptedTimestamp);
 					++reqData->step;
 					break;
 				}
diff --git a/src/libpiano/xml.c b/src/libpiano/xml.c
index ce1074a..a327e82 100644
--- a/src/libpiano/xml.c
+++ b/src/libpiano/xml.c
@@ -256,7 +256,7 @@ static void PianoXmlParsePlaylistCb (const char *key, const ezxml_t value,
 		/* don't try to decrypt if string is too short (=> invalid memory
 		 * reads/writes) */
 		if (valueStrN > urlTailN &&
-				(urlTail = PianoDecryptString (urlTailCrypted)) != NULL) {
+				(urlTail = PianoDecryptString (urlTailCrypted, NULL)) != NULL) {
 			if ((song->audioUrl = calloc (valueStrN + 1,
 					sizeof (*song->audioUrl))) != NULL) {
 				memcpy (song->audioUrl, valueStr, valueStrN - urlTailN);
-- 
cgit v1.2.3