From 9818d67ec27bbc39feaf4c1a1f3d35a029484cc9 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Mon, 9 Jan 2006 14:39:40 +0000 Subject: [PATCH] Make the tagstruct handling safe on machines with alignment restrictions. git-svn-id: file:///home/lennart/svn/public/pulseaudio/branches/ossman@427 fefdeb5f-60dc-0310-8127-8f9354f1896f --- polyp/tagstruct.c | 65 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/polyp/tagstruct.c b/polyp/tagstruct.c index 59178bf..ff444e3 100644 --- a/polyp/tagstruct.c +++ b/polyp/tagstruct.c @@ -125,7 +125,8 @@ void pa_tagstruct_putu32(struct pa_tagstruct*t, uint32_t i) { assert(t); extend(t, 5); t->data[t->length] = TAG_U32; - *((uint32_t*) (t->data+t->length+1)) = htonl(i); + i = htonl(i); + memcpy(t->data+t->length+1, &i, 4); t->length += 5; } @@ -138,12 +139,14 @@ void pa_tagstruct_putu8(struct pa_tagstruct*t, uint8_t c) { } void pa_tagstruct_put_sample_spec(struct pa_tagstruct *t, const struct pa_sample_spec *ss) { + uint32_t rate; assert(t && ss); extend(t, 7); t->data[t->length] = TAG_SAMPLE_SPEC; t->data[t->length+1] = (uint8_t) ss->format; t->data[t->length+2] = ss->channels; - *(uint32_t*) (t->data+t->length+3) = htonl(ss->rate); + rate = htonl(ss->rate); + memcpy(t->data+t->length+3, &rate, 4); t->length += 7; } @@ -152,9 +155,10 @@ void pa_tagstruct_put_arbitrary(struct pa_tagstruct *t, const void *p, size_t le extend(t, 5+length); t->data[t->length] = TAG_ARBITRARY; - *((uint32_t*) (t->data+t->length+1)) = htonl(length); if (length) memcpy(t->data+t->length+5, p, length); + length = htonl(length); + memcpy(t->data+t->length+1, &length, 4); t->length += 5+length; } @@ -166,29 +170,38 @@ void pa_tagstruct_put_boolean(struct pa_tagstruct*t, int b) { } void pa_tagstruct_put_timeval(struct pa_tagstruct*t, const struct timeval *tv) { + uint32_t tmp; assert(t); extend(t, 9); t->data[t->length] = TAG_TIMEVAL; - *((uint32_t*) (t->data+t->length+1)) = htonl(tv->tv_sec); - *((uint32_t*) (t->data+t->length+5)) = htonl(tv->tv_usec); + tmp = htonl(tv->tv_sec); + memcpy(t->data+t->length+1, &tmp, 4); + tmp = htonl(tv->tv_usec); + memcpy(t->data+t->length+5, &tmp, 4); t->length += 9; } void pa_tagstruct_put_usec(struct pa_tagstruct*t, pa_usec_t u) { + uint32_t tmp; assert(t); extend(t, 9); t->data[t->length] = TAG_USEC; - *((uint32_t*) (t->data+t->length+1)) = htonl((uint32_t) (u >> 32)); - *((uint32_t*) (t->data+t->length+5)) = htonl((uint32_t) u); + tmp = htonl((uint32_t) (u >> 32)); + memcpy(t->data+t->length+1, &tmp, 4); + tmp = htonl((uint32_t) u); + memcpy(t->data+t->length+5, &tmp, 4); t->length += 9; } void pa_tagstruct_putu64(struct pa_tagstruct*t, uint64_t u) { + uint32_t tmp; assert(t); extend(t, 9); t->data[t->length] = TAG_U64; - *((uint32_t*) (t->data+t->length+1)) = htonl((uint32_t) (u >> 32)); - *((uint32_t*) (t->data+t->length+5)) = htonl((uint32_t) u); + tmp = htonl((uint32_t) (u >> 32)); + memcpy(t->data+t->length+1, &tmp, 4); + tmp = htonl((uint32_t) u); + memcpy(t->data+t->length+5, &tmp, 4); t->length += 9; } @@ -237,8 +250,9 @@ int pa_tagstruct_getu32(struct pa_tagstruct*t, uint32_t *i) { if (t->data[t->rindex] != TAG_U32) return -1; - - *i = ntohl(*((uint32_t*) (t->data+t->rindex+1))); + + memcpy(i, t->data+t->rindex+1, 4); + *i = ntohl(*i); t->rindex += 5; return 0; } @@ -268,13 +282,15 @@ int pa_tagstruct_get_sample_spec(struct pa_tagstruct *t, struct pa_sample_spec * ss->format = t->data[t->rindex+1]; ss->channels = t->data[t->rindex+2]; - ss->rate = ntohl(*(uint32_t*) (t->data+t->rindex+3)); + memcpy(&ss->rate, t->data+t->rindex+3, 4); + ss->rate = ntohl(ss->rate); t->rindex += 7; return 0; } int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t length) { + uint32_t len; assert(t && p); if (t->rindex+5+length > t->length) @@ -283,7 +299,8 @@ int pa_tagstruct_get_arbitrary(struct pa_tagstruct *t, const void **p, size_t le if (t->data[t->rindex] != TAG_ARBITRARY) return -1; - if (ntohl(*((uint32_t*) (t->data+t->rindex+1))) != length) + memcpy(&len, t->data+t->rindex+1, 4); + if (ntohl(len) != length) return -1; *p = t->data+t->rindex+5; @@ -326,15 +343,18 @@ int pa_tagstruct_get_timeval(struct pa_tagstruct*t, struct timeval *tv) { if (t->data[t->rindex] != TAG_TIMEVAL) return -1; - - tv->tv_sec = ntohl(*((uint32_t*) (t->data+t->rindex+1))); - tv->tv_usec = ntohl(*((uint32_t*) (t->data+t->rindex+5))); + + memcpy(&tv->tv_sec, t->data+t->rindex+1, 4); + tv->tv_sec = ntohl(tv->tv_sec); + memcpy(&tv->tv_usec, t->data+t->rindex+5, 4); + tv->tv_usec = ntohl(tv->tv_usec); t->rindex += 9; return 0; } int pa_tagstruct_get_usec(struct pa_tagstruct*t, pa_usec_t *u) { + uint32_t tmp; assert(t && u); if (t->rindex+9 > t->length) @@ -343,13 +363,16 @@ int pa_tagstruct_get_usec(struct pa_tagstruct*t, pa_usec_t *u) { if (t->data[t->rindex] != TAG_USEC) return -1; - *u = (pa_usec_t) ntohl(*((uint32_t*) (t->data+t->rindex+1))) << 32; - *u |= (pa_usec_t) ntohl(*((uint32_t*) (t->data+t->rindex+5))); + memcpy(&tmp, t->data+t->rindex+1, 4); + *u = (pa_usec_t) ntohl(tmp) << 32; + memcpy(&tmp, t->data+t->rindex+5, 4); + *u |= (pa_usec_t) ntohl(tmp); t->rindex +=9; return 0; } int pa_tagstruct_getu64(struct pa_tagstruct*t, uint64_t *u) { + uint32_t tmp; assert(t && u); if (t->rindex+9 > t->length) @@ -358,8 +381,10 @@ int pa_tagstruct_getu64(struct pa_tagstruct*t, uint64_t *u) { if (t->data[t->rindex] != TAG_U64) return -1; - *u = (uint64_t) ntohl(*((uint32_t*) (t->data+t->rindex+1))) << 32; - *u |= (uint64_t) ntohl(*((uint32_t*) (t->data+t->rindex+5))); + memcpy(&tmp, t->data+t->rindex+1, 4); + *u = (pa_usec_t) ntohl(tmp) << 32; + memcpy(&tmp, t->data+t->rindex+5, 4); + *u |= (pa_usec_t) ntohl(tmp); t->rindex +=9; return 0; } -- 2.7.4