diff options
author | Haynes Mathew George <hgeorge@codeaurora.org> | 2018-03-12 14:28:40 -0700 |
---|---|---|
committer | Mikhail Naganov <mnaganov@google.com> | 2018-03-14 15:53:32 -0700 |
commit | 8b7274b2ec686c87673bf39328381acbdea1a333 (patch) | |
tree | 3f392fb80804eead5e9e36d28a5c3bc8fa886b3c | |
parent | b3332a0aef38410330e6cd792c3e47aeddac715e (diff) | |
download | tinyalsa-8b7274b2ec686c87673bf39328381acbdea1a333.tar.gz |
tinyplay: play PCM up to size specified in the header
tinyplay plays to the end of file without checking whether playback
goes beyond end of data section which its size is specified in the
RIFF wave header. This could lead to playing out unwanted data which
is placed at the end of file.
authored-by: Patrick Lai <plai@codeaurora.org>
Change-Id: I17bd3f6ebca4813f8987585472208c1f52696cae
-rw-r--r-- | tinyplay.c | 18 |
1 files changed, 11 insertions, 7 deletions
@@ -32,6 +32,7 @@ #include <stdint.h> #include <string.h> #include <signal.h> +#include <endian.h> #define ID_RIFF 0x46464952 #define ID_WAVE 0x45564157 @@ -62,7 +63,7 @@ static int close = 0; void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, unsigned int rate, unsigned int bits, unsigned int period_size, - unsigned int period_count); + unsigned int period_count, uint32_t data_sz); void stream_close(int sig) { @@ -118,6 +119,7 @@ int main(int argc, char **argv) case ID_DATA: /* Stop looking for chunks */ more_chunks = 0; + chunk_header.sz = le32toh(chunk_header.sz); break; default: /* Unknown chunk, skip bytes */ @@ -153,7 +155,7 @@ int main(int argc, char **argv) } play_sample(file, card, device, chunk_fmt.num_channels, chunk_fmt.sample_rate, - chunk_fmt.bits_per_sample, period_size, period_count); + chunk_fmt.bits_per_sample, period_size, period_count, chunk_header.sz); fclose(file); @@ -210,12 +212,12 @@ int sample_is_playable(unsigned int card, unsigned int device, unsigned int chan void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, unsigned int rate, unsigned int bits, unsigned int period_size, - unsigned int period_count) + unsigned int period_count, uint32_t data_sz) { struct pcm_config config; struct pcm *pcm; char *buffer; - int size; + unsigned int size, read_sz; int num_read; memset(&config, 0, sizeof(config)); @@ -253,20 +255,22 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in return; } - printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits); + printf("Playing sample: %u ch, %u hz, %u bit %u bytes\n", channels, rate, bits, data_sz); /* catch ctrl-c to shutdown cleanly */ signal(SIGINT, stream_close); do { - num_read = fread(buffer, 1, size, file); + read_sz = size < data_sz ? size : data_sz; + num_read = fread(buffer, 1, read_sz, file); if (num_read > 0) { if (pcm_write(pcm, buffer, num_read)) { fprintf(stderr, "Error playing sample\n"); break; } + data_sz -= num_read; } - } while (!close && num_read > 0); + } while (!close && num_read > 0 && data_sz > 0); free(buffer); pcm_close(pcm); |