aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHaynes Mathew George <hgeorge@codeaurora.org>2018-03-12 14:28:40 -0700
committerMikhail Naganov <mnaganov@google.com>2018-03-14 15:53:32 -0700
commit8b7274b2ec686c87673bf39328381acbdea1a333 (patch)
tree3f392fb80804eead5e9e36d28a5c3bc8fa886b3c
parentb3332a0aef38410330e6cd792c3e47aeddac715e (diff)
downloadtinyalsa-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.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/tinyplay.c b/tinyplay.c
index 461a4ef..0354df6 100644
--- a/tinyplay.c
+++ b/tinyplay.c
@@ -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);