1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <stddef.h>
6 
7 #include "base/numerics/safe_conversions.h"
8 #include "base/optional.h"
9 #include "media/video/h264_parser.h"
10 #include "ui/gfx/geometry/rect.h"
11 #include "ui/gfx/geometry/size.h"
12 
13 static volatile size_t volatile_sink;
14 
15 // Entry point for LibFuzzer.
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)16 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
17   if (!size)
18     return 0;
19 
20   media::H264Parser parser;
21   parser.SetStream(data, base::checked_cast<off_t>(size));
22 
23   // Parse until the end of stream/unsupported stream/error in stream is
24   // found.
25   while (true) {
26     media::H264NALU nalu;
27     media::H264Parser::Result res = parser.AdvanceToNextNALU(&nalu);
28     if (res != media::H264Parser::kOk)
29       break;
30 
31     switch (nalu.nal_unit_type) {
32       case media::H264NALU::kIDRSlice:
33       case media::H264NALU::kNonIDRSlice: {
34         media::H264SliceHeader shdr;
35         res = parser.ParseSliceHeader(nalu, &shdr);
36         break;
37       }
38 
39       case media::H264NALU::kSPS: {
40         int id;
41         res = parser.ParseSPS(&id);
42         if (res != media::H264Parser::kOk)
43           break;
44         const media::H264SPS* sps = parser.GetSPS(id);
45         if (!sps)
46           break;
47         // Also test the SPS helper methods. We make sure that the results are
48         // used so that the calls are not optimized away.
49         base::Optional<gfx::Size> coded_size = sps->GetCodedSize();
50         volatile_sink = coded_size.value_or(gfx::Size()).ToString().length();
51         base::Optional<gfx::Rect> visible_rect = sps->GetVisibleRect();
52         volatile_sink = visible_rect.value_or(gfx::Rect()).ToString().length();
53         break;
54       }
55 
56       case media::H264NALU::kPPS: {
57         int id;
58         res = parser.ParsePPS(&id);
59         break;
60       }
61 
62       case media::H264NALU::kSEIMessage: {
63         media::H264SEIMessage sei_msg;
64         res = parser.ParseSEI(&sei_msg);
65         break;
66       }
67 
68       default:
69         // Skip any other NALU.
70         break;
71     }
72     if (res != media::H264Parser::kOk)
73       break;
74   }
75 
76   return 0;
77 }
78