Handle all permissible PCM fields with WavReader.

I discovered the hard way that Adobe Audition writes an 18 byte format
header with an extra (zero) extension size field. Although:
https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
indicates this field shouldn't exist for PCM, the documentation here:
http://www-mmsp.ece.mcgill.ca/documents/AudioFormats/WAVE/WAVE.html
doesn't list it as strictly forbidden, only that it _must_ exist for
non-PCM formats.

Audition can write metadata to the file after the audio data, which is
also not forbidden. We now ensure to read only up to the audio payload
length to avoid reading the metadata.

R=aluebs@webrtc.org, kwiberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/33629004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7915 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/common_audio/wav_header.cc b/webrtc/common_audio/wav_header.cc
index 8c781fb..9776bc4 100644
--- a/webrtc/common_audio/wav_header.cc
+++ b/webrtc/common_audio/wav_header.cc
@@ -17,6 +17,7 @@
 #include <algorithm>
 #include <cstring>
 #include <limits>
+#include <string>
 
 #include "webrtc/base/checks.h"
 #include "webrtc/common_audio/include/audio_util.h"
@@ -178,14 +179,31 @@
   memcpy(buf, &header, kWavHeaderSize);
 }
 
-bool ReadWavHeader(const uint8_t* buf,
+bool ReadWavHeader(ReadableWav* readable,
                    int* num_channels,
                    int* sample_rate,
                    WavFormat* format,
                    int* bytes_per_sample,
                    uint32_t* num_samples) {
   WavHeader header;
-  memcpy(&header, buf, kWavHeaderSize);
+  if (readable->Read(&header, kWavHeaderSize - sizeof(header.data)) !=
+      kWavHeaderSize - sizeof(header.data))
+    return false;
+
+  const uint32_t fmt_size = ReadLE32(header.fmt.header.Size);
+  if (fmt_size != kFmtSubchunkSize) {
+    // There is an optional two-byte extension field permitted to be present
+    // with PCM, but which must be zero.
+    int16_t ext_size;
+    if (kFmtSubchunkSize + sizeof(ext_size) != fmt_size)
+      return false;
+    if (readable->Read(&ext_size, sizeof(ext_size)) != sizeof(ext_size))
+      return false;
+    if (ext_size != 0)
+      return false;
+  }
+  if (readable->Read(&header.data, sizeof(header.data)) != sizeof(header.data))
+    return false;
 
   // Parse needed fields.
   *format = static_cast<WavFormat>(ReadLE16(header.fmt.AudioFormat));
@@ -207,9 +225,7 @@
   if (ReadFourCC(header.data.header.ID) != "data")
     return false;
 
-  if (ReadLE32(header.riff.header.Size) != RiffChunkSize(bytes_in_payload))
-    return false;
-  if (ReadLE32(header.fmt.header.Size) != kFmtSubchunkSize)
+  if (ReadLE32(header.riff.header.Size) < RiffChunkSize(bytes_in_payload))
     return false;
   if (ReadLE32(header.fmt.ByteRate) !=
       ByteRate(*num_channels, *sample_rate, *bytes_per_sample))