| /* | 
 |  * Copyright 2019 Google, LLC | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #include "fuzz/Fuzz.h" | 
 | #include "src/core/SkDescriptor.h" | 
 | #include "src/core/SkScalerContext.h" | 
 |  | 
 | DEF_FUZZ(SkDescriptor, fuzz) { | 
 |     int32_t numEntries; | 
 |     fuzz->next(&numEntries); | 
 |  | 
 |     // Limit this to keep the fuzz operations fast. | 
 |     if (numEntries < 0 || numEntries > 300) { | 
 |         return; | 
 |     } | 
 |  | 
 |     size_t overhead = SkDescriptor::ComputeOverhead(numEntries); | 
 |     size_t data; | 
 |     fuzz->nextRange(&data, 0, 500); | 
 |     auto desc = SkDescriptor::Alloc(overhead + data); | 
 |     for (int32_t i = 0; i<numEntries && !fuzz->exhausted(); i++) { | 
 |         uint32_t tag; | 
 |         fuzz->next(&tag); | 
 |         // Valid use of the API requires that tag is truthy and that | 
 |         // the length is aligned to 4. If the fuzzed data doesn't conform, | 
 |         // return to signal that this is "boring" data. | 
 |         if (!tag) { | 
 |             return; | 
 |         } | 
 |         size_t length; | 
 |         fuzz->next(&length); | 
 |         if (SkAlign4(length) != length) { | 
 |             return; | 
 |         } | 
 |  | 
 |         uint8_t choice; | 
 |         fuzz->nextRange(&choice, 0, 1); | 
 |         switch(choice) { | 
 |             case 0: { // use SkScalerContextRec | 
 |                 SkScalerContextRec rec; | 
 |                 fuzz->next(&rec); | 
 |                 desc->addEntry(tag, sizeof(rec), &rec); | 
 |                 break; | 
 |             } | 
 |             case 1: { // use arbitrary data | 
 |                 if (fuzz->remaining() < length) { | 
 |                     // Can't initialize all that we requested, so bail out. | 
 |                     return; | 
 |                 } | 
 |                 uint8_t* bytes = new uint8_t[length]; | 
 |                 fuzz->nextN(bytes, length); | 
 |                 desc->addEntry(tag, length, bytes); | 
 |                 delete[] bytes; | 
 |                 break; | 
 |             } | 
 |             default: { | 
 |                 SK_ABORT("Did you update the range in FuzzSkDescriptor?"); | 
 |             } | 
 |         } | 
 |     } | 
 |  | 
 |     // Exercise the API to make sure we don't step out of bounds, etc. | 
 |  | 
 |     if (desc->isValid()) { | 
 |         desc->computeChecksum(); | 
 |  | 
 |         uint32_t tagToFind; | 
 |         fuzz->next(&tagToFind); | 
 |  | 
 |         uint32_t ignore; | 
 |         desc->findEntry(tagToFind, &ignore); | 
 |     } | 
 | } |