From d5221655dfd1a2156aa6be83b5aadea7c1e0f5bd Mon Sep 17 00:00:00 2001
From: Ron <ron@debian.org>
Date: Sat, 13 Jan 2018 20:19:20 +1030
Subject: [PATCH] Check memory allocations for success

Adds some missing checks spotted by eye in a visual review while looking
into the details of https://bugs.debian.org/870608
---
 src/audio_out.c                | 58 +++++++++++++++++++++++++---------
 src/plugins/macosx/ao_macosx.c |  2 +-
 src/plugins/sndio/ao_sndio.c   |  3 ++
 3 files changed, 47 insertions(+), 16 deletions(-)

--- a/src/audio_out.c
+++ b/src/audio_out.c
@@ -634,6 +634,10 @@ static char *_sanitize_matrix(int maxcha
     char *ret = calloc(strlen(matrix)+1,1); /* can only get smaller */
     char *p=matrix;
     int count=0;
+
+    if(!ret)
+      return NULL;
+
     while(count<maxchannels){
       char *h,*t;
       int m=0;
@@ -707,6 +711,15 @@ static int _find_channel(int needle, cha
   return -1;
 }
 
+static void _free_map(char **m){
+  char **in=m;
+  while(m && *m){
+    free(*m);
+    m++;
+  }
+  if(in)free(in);
+}
+
 static char **_tokenize_matrix(char *matrix){
   char **ret=NULL;
   char *p=matrix;
@@ -731,6 +744,8 @@ static char **_tokenize_matrix(char *mat
   }
 
   ret = calloc(count+1,sizeof(*ret));
+  if(!ret)
+    return NULL;
 
   p=matrix;
   count=0;
@@ -749,6 +764,10 @@ static char **_tokenize_matrix(char *mat
     while(t>p && isspace(*(t-1)))t--;
 
     ret[count] = calloc(t-p+1,1);
+    if(!ret[count]){
+      _free_map(ret);
+      return NULL;
+    }
     memcpy(ret[count],p,t-p);
     count++;
     if(!*h)break;
@@ -756,16 +775,6 @@ static char **_tokenize_matrix(char *mat
   }
 
   return ret;
-
-}
-
-static void _free_map(char **m){
-  char **in=m;
-  while(m && *m){
-    free(*m);
-    m++;
-  }
-  if(in)free(in);
 }
 
 static unsigned int _matrix_to_channelmask(int ch, char *matrix, char *premap, int **mout){
@@ -773,7 +782,14 @@ static unsigned int _matrix_to_channelma
   char *p=matrix;
   int *perm=(*mout=malloc(ch*sizeof(*mout)));
   int i;
-  char **map = _tokenize_matrix(premap);
+  char **map;
+
+  if(!perm)
+    return 0;
+
+  map = _tokenize_matrix(premap);
+  if(!map)
+    return 0;
 
   for(i=0;i<ch;i++) perm[i] = -1;
   i=0;
@@ -811,6 +827,9 @@ static char *_channelmask_to_matrix(unsi
   char buffer[257]={0};
   char **map = _tokenize_matrix(premap);
 
+  if(!map)
+    return NULL;
+
   while(map[m]){
     if(mask & (1<<m)){
       if(count)
@@ -850,6 +869,9 @@ static char *_matrix_intersect(char *mat
   int count=0;
   char **map = _tokenize_matrix(premap);
 
+  if(!map)
+    return NULL;
+
   while(1){
     char *h=p;
     int m=0;
@@ -1040,7 +1062,7 @@ static ao_device* _open_device(int drive
                                                          device->output_matrix,
                                                          &device->input_map);
               int channels = _channelmask_bits(mask);
-              if(channels<0){
+              if(channels<=0){
                 aerror("Unable to map any channels from input matrix to output");
                 errno = AO_EBADFORMAT;
                 goto error;
@@ -1061,7 +1083,7 @@ static ao_device* _open_device(int drive
                                                          device->output_matrix,
                                                          &device->input_map);
               int channels = _channelmask_bits(mask);
-              if(channels<0){
+              if(channels<=0){
                 aerror("Unable to map any channels from input matrix to output");
                 errno = AO_EBADFORMAT;
                 goto error;
@@ -1112,6 +1134,10 @@ static ao_device* _open_device(int drive
             int count=0;
             device->inter_permute = calloc(device->output_channels,sizeof(int));
 
+            if (!device->inter_permute) {
+              errno = AO_EFAIL;
+              goto error;
+            }
             adebug("\n");
 
             while(count<device->output_channels){
@@ -1158,8 +1184,10 @@ static ao_device* _open_device(int drive
                 for(i=0;i<device->output_channels;i++)
                   if(device->inter_permute[i]==j)break;
                 if(i==device->output_channels){
-                  adebug("input %d (%s)\t -> none\n",
-                         j,inch[j]);
+                  if(inch){
+                    adebug("input %d (%s)\t -> none\n",
+                           j,inch[j]);
+                  }
                   unflag=1;
                 }
               }
--- a/src/plugins/macosx/ao_macosx.c
+++ b/src/plugins/macosx/ao_macosx.c
@@ -592,11 +592,11 @@ int ao_plugin_open(ao_device *device, ao
   internal->firstValidByteOffset = 0;
   internal->validByteCount = 0;
   internal->buffer = malloc(internal->bufferByteCount);
-  memset(internal->buffer, 0, internal->bufferByteCount);
   if (!internal->buffer) {
     aerror("Unable to allocate queue buffer.\n");
     return 0;
   }
+  memset(internal->buffer, 0, internal->bufferByteCount);
 
   /* limited to stereo for now */
   //if(!device->output_matrix)
--- a/src/plugins/sndio/ao_sndio.c
+++ b/src/plugins/sndio/ao_sndio.c
@@ -67,6 +67,9 @@ int ao_plugin_device_init(ao_device *dev
 {
   ao_sndio_internal *internal;
   internal = (ao_sndio_internal *) calloc(1,sizeof(*internal));
+  if (internal == NULL)
+    return 0;
+
   internal->id=-1;
   device->internal = internal;
   device->output_matrix_order = AO_OUTPUT_MATRIX_FIXED;
