{"record":{"id":"3a1d1fe6b273cdbe","repo":"microg/GmsCore","slug":"certdata-to-small","errorCode":null,"errorMessage":"CertData to small","messagePattern":"CertData to small","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"play-services-basement/src/main/java/com/google/android/gms/common/internal/CertData.java","lineNumber":34,"sourceCode":"\npackage com.google.android.gms.common.internal;\n\nimport android.os.IBinder;\nimport android.os.RemoteException;\n\nimport androidx.annotation.Nullable;\nimport com.google.android.gms.dynamic.IObjectWrapper;\nimport com.google.android.gms.dynamic.ObjectWrapper;\n\nimport java.util.Arrays;\n\npublic class CertData extends ICertData.Stub {\n    private final byte[] bytes;\n    private final int hashCode;\n\n    public CertData(byte[] bytes) {\n        this.bytes = bytes;\n        if (bytes.length < 25) throw new RuntimeException(\"CertData to small\");\n        hashCode = Arrays.hashCode(Arrays.copyOfRange(bytes, 0, 25));\n    }\n\n    @Override\n    public int hashCode() {\n        return hashCode;\n    }\n\n    @Override\n    public boolean equals(Object obj) {\n        if (!(obj instanceof ICertData)) return false;\n        ICertData cert = (ICertData) obj;\n        try {\n            if (cert.remoteHashCode() != hashCode()) return false;\n            return Arrays.equals(ObjectWrapper.unwrapTyped(cert.getWrappedBytes(), byte[].class), getBytes());\n        } catch (RemoteException e) {\n            return false;\n        }","sourceCodeStart":16,"sourceCodeEnd":52,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-basement/src/main/java/com/google/android/gms/common/internal/CertData.java#L16-L52","documentation":"CertData wraps a certificate byte array and requires at least 25 bytes, since its hashCode is computed over the first 25 bytes. It throws RuntimeException (not a checked exception) when the provided byte array is shorter, indicating the input is not a valid certificate blob for this protocol.","triggerScenarios":"Calling new CertData(bytes) with a byte[] shorter than 25 bytes, e.g. an empty array, truncated certificate, or wrong data passed in.","commonSituations":"Reading a corrupted or truncated package signature; passing the wrong field (e.g. a hash instead of full cert data) from package info.","solutions":["Verify the certificate byte array length (>= 25) before constructing CertData","Ensure the full signature/certificate bytes are passed, not a truncated or derived value","Re-acquire the certificate data from Signature[] / PackageManager if it was corrupted"],"exampleFix":"// before\nCertData cert = new CertData(sig.get.toByteArray()); // may be truncated\n// after\nbyte[] b = sig.get.toByteArray();\nif (b.length < 25) throw new BadCertificateException(\"cert too small\");\nCertData cert = new CertData(b);","handlingStrategy":"validation","validationCode":"byte[] b = signature.toByteArray();\nif (b != null && b.length >= 25) {\n    CertData cert = new CertData(b);\n}","typeGuard":null,"tryCatchPattern":"try { new CertData(bytes); } catch (RuntimeException e) { /* reject invalid cert blob */ }","preventionTips":["Pass full certificate bytes, never truncated hashes","Validate minimum length before constructing"],"tags":["certificate","validation","internal"],"backgroundTag":"invalid-argument-value","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}