Do proper bounds checking in formats (bug #1356)
[asterisk/asterisk.git] / formats / format_gsm.c
index 88ca9fd..d58039e 100755 (executable)
 #endif
 #include "msgsm.h"
 
-
 /* Some Ideas for this code came from makegsme.c by Jeffrey Chilton */
 
 /* Portions of the conversion code are by guido@sienanet.it */
 
+/* silent gsm frame */
+/* begin binary data: */
+char gsm_silence[] = /* 33 */
+{0xD8,0x20,0xA2,0xE1,0x5A,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49
+,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24,0x92,0x49,0x24,0x50,0x00,0x49,0x24
+,0x92,0x49,0x24};
+/* end binary data. size = 33 bytes */
+
 struct ast_filestream {
        void *reserved[AST_RESERVED_POINTERS];
        /* Believe it or not, we must decode/recode to account for the
@@ -190,9 +197,16 @@ static int gsm_seek(struct ast_filestream *fs, long sample_offset, int whence)
                offset = distance + cur;
        else if(whence == SEEK_END)
                offset = max - distance;
+       // Always protect against seeking past the begining.
+       offset = (offset < min)?min:offset;
        if (whence != SEEK_FORCECUR) {
                offset = (offset > max)?max:offset;
-               offset = (offset < min)?min:offset;
+       } else if (offset > max) {
+               int i;
+               lseek(fs->fd, 0, SEEK_END);
+               for (i=0; i< (offset - max) / 33; i++) {
+                       write(fs->fd, gsm_silence, 33);
+               }
        }
        return lseek(fs->fd, offset, SEEK_SET);
 }