Switch persistent cache to use SkReadBuffer/SkWriteBuffer

These are much safer than SkReader32/SkWriter32 (they do validation and
ensure we never read past the end of the buffer).

Where we used to just assert that the contents of the cache were valid,
we now validate everything, and fail gracefully by discarding the cache
contents if it's corrupted or invalid.

Bug: skia:9402
Change-Id: Ib893681f97f9413c28744f11075dc2e392364db6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294998
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/gpu/GrPersistentCacheUtils.h b/src/gpu/GrPersistentCacheUtils.h
index fe932c2..317d75d 100644
--- a/src/gpu/GrPersistentCacheUtils.h
+++ b/src/gpu/GrPersistentCacheUtils.h
@@ -10,8 +10,8 @@
 
 #include "include/core/SkData.h"
 #include "include/private/GrTypesPriv.h"
-#include "src/core/SkReader32.h"
-#include "src/core/SkWriter32.h"
+#include "src/core/SkReadBuffer.h"
+#include "src/core/SkWriteBuffer.h"
 #include "src/sksl/SkSLString.h"
 #include "src/sksl/ir/SkSLProgram.h"
 
@@ -28,7 +28,7 @@
 };
 
 // Increment this whenever the serialization format of cached shaders changes
-static constexpr int kCurrentVersion = 1;
+static constexpr int kCurrentVersion = 2;
 
 static inline sk_sp<SkData> PackCachedShaders(SkFourByteTag shaderType,
                                               const SkSL::String shaders[],
@@ -39,12 +39,12 @@
     // kGrShaderTypeCount inputs. If the backend gives us fewer, we just replicate the last one.
     SkASSERT(numInputs >= 1 && numInputs <= kGrShaderTypeCount);
 
-    SkWriter32 writer;
-    writer.write32(kCurrentVersion);
-    writer.write32(shaderType);
+    SkBinaryWriteBuffer writer;
+    writer.writeInt(kCurrentVersion);
+    writer.writeUInt(shaderType);
     for (int i = 0; i < kGrShaderTypeCount; ++i) {
-        writer.writeString(shaders[i].c_str(), shaders[i].size());
-        writer.writePad(&inputs[std::min(i, numInputs - 1)], sizeof(SkSL::Program::Inputs));
+        writer.writeByteArray(shaders[i].c_str(), shaders[i].size());
+        writer.writePad32(&inputs[std::min(i, numInputs - 1)], sizeof(SkSL::Program::Inputs));
     }
     writer.writeBool(SkToBool(meta));
     if (meta) {
@@ -57,7 +57,7 @@
 
         writer.writeInt(meta->fAttributeNames.count());
         for (const auto& attr : meta->fAttributeNames) {
-            writer.writeString(attr.c_str(), attr.size());
+            writer.writeByteArray(attr.c_str(), attr.size());
         }
 
         writer.writeBool(meta->fHasCustomColorOutput);
@@ -66,30 +66,26 @@
     return writer.snapshotAsData();
 }
 
-static SkFourByteTag GetType(SkReader32* reader) {
+static SkFourByteTag GetType(SkReadBuffer* reader) {
     constexpr SkFourByteTag kInvalidTag = ~0;
-    if (!reader->isAvailable(2 * sizeof(int))) {
-        return kInvalidTag;
-    }
-    if (reader->readInt() != kCurrentVersion) {
-        return kInvalidTag;
-    }
-    return reader->readU32();
+    int version           = reader->readInt();
+    SkFourByteTag typeTag = reader->readUInt();
+    return reader->validate(version == kCurrentVersion) ? typeTag : kInvalidTag;
 }
 
-static inline void UnpackCachedShaders(SkReader32* reader,
+static inline bool UnpackCachedShaders(SkReadBuffer* reader,
                                        SkSL::String shaders[],
                                        SkSL::Program::Inputs inputs[],
                                        int numInputs,
                                        ShaderMetadata* meta = nullptr) {
     for (int i = 0; i < kGrShaderTypeCount; ++i) {
-        size_t stringLen = 0;
-        const char* string = reader->readString(&stringLen);
-        shaders[i] = SkSL::String(string, stringLen);
+        uint32_t shaderLen = reader->getArrayCount();
+        shaders[i].resize(shaderLen);
+        reader->readByteArray(shaders[i].data(), shaderLen);
 
         // GL, for example, only wants one set of Inputs
         if (i < numInputs) {
-            reader->read(&inputs[i], sizeof(inputs[i]));
+            reader->readPad32(&inputs[i], sizeof(inputs[i]));
         } else {
             reader->skip(sizeof(SkSL::Program::Inputs));
         }
@@ -104,15 +100,22 @@
         }
 
         meta->fAttributeNames.resize(reader->readInt());
-        for (int i = 0; i < meta->fAttributeNames.count(); ++i) {
-            size_t stringLen = 0;
-            const char* string = reader->readString(&stringLen);
-            meta->fAttributeNames[i] = SkSL::String(string, stringLen);
+        for (auto& attr : meta->fAttributeNames) {
+            uint32_t attrLen = reader->getArrayCount();
+            attr.resize(attrLen);
+            reader->readByteArray(attr.data(), attrLen);
         }
 
         meta->fHasCustomColorOutput    = reader->readBool();
         meta->fHasSecondaryColorOutput = reader->readBool();
     }
+
+    if (!reader->isValid()) {
+        for (int i = 0; i < kGrShaderTypeCount; ++i) {
+            shaders[i].clear();
+        }
+    }
+    return reader->isValid();
 }
 
 }