diff options
Diffstat (limited to 'src/modules/organya.c')
-rw-r--r-- | src/modules/organya.c | 35 |
1 files changed, 29 insertions, 6 deletions
diff --git a/src/modules/organya.c b/src/modules/organya.c index 9d7bb67..d214ed2 100644 --- a/src/modules/organya.c +++ b/src/modules/organya.c @@ -9,7 +9,7 @@ #include "../include.h" // assumes little endian architechture, sorry -// C port of the 250 SLoC of JS organya player https://github.com/alula/organya-js +// my C port of the 250 SLoC of JS organya player https://github.com/alula/organya-js struct song { uint16_t wait; @@ -68,19 +68,28 @@ static struct drums { int samples; } *drums = NULL; -void freefunc(void *ptr) { - struct organya *self = ptr; +void freesong(struct song *song) { for (int i = 0; i < 16; i++) { - free(self->song->tracks[i]); + free(song->tracks[i]); } - free(self->song); + free(song); +} + +void freefunc(void *ptr) { + struct organya *self = ptr; + freesong(self->song); free(self); } struct song *song_constructor(struct blob *file) { char const *p = file->data; + size_t bytes = file->size; // header check + if (bytes < 6) { + return NULL; + } + bytes -= 6; uint32_t const org1 = *(uint32_t *) p; p += sizeof (uint32_t); uint16_t const orgVersion = *(uint16_t *) p; p += sizeof (uint16_t); if (org1 != 0x2d67724f || orgVersion != 0x3230) { @@ -92,12 +101,20 @@ struct song *song_constructor(struct blob *file) { return NULL; } + if (bytes < 12) { + return NULL; + } + bytes -= 12; self->wait = *(uint16_t *) p; p += sizeof (uint16_t); self->meas[0] = *(uint8_t *) p; p += sizeof (uint8_t); self->meas[1] = *(uint8_t *) p; p += sizeof (uint8_t); self->start = *(int32_t *) p; p += sizeof (int32_t); self->end = *(int32_t *) p; p += sizeof (int32_t); + if (bytes < 6 * 16) { + return NULL; + } + bytes -= 6 * 16; for (int i = 0; i < 16; i++) { self->instruments[i].freq = *(uint16_t *) p; p+= sizeof (uint16_t); self->instruments[i].wave = *(uint8_t *) p; p += sizeof (uint8_t); @@ -113,10 +130,16 @@ struct song *song_constructor(struct blob *file) { size_t const length = self->instruments[i].notes; struct track *track = malloc(sizeof (track) * length); if (track == NULL && length != 0) { - //freefunc(self); // TODO: this looks really wrong + freesong(self); return NULL; } + if (bytes < 8 * length) { + freesong(self); + return NULL; + } + bytes -= 8 * length; + for (unsigned j = 0; j < length; j++) { track[j].pos = *(int32_t *) p; p += sizeof (int32_t); } |