From c6fc94e7bd65e15315e94a66f001c7c29d4cbc42 Mon Sep 17 00:00:00 2001 From: "Yevhen Babiichuk (DustDFG)" Date: Fri, 9 Jan 2026 15:26:43 +0200 Subject: [PATCH] Convert newpipe/settings/export/PreferencesObjectInputStream to kotlin --- .../export/PreferencesObjectInputStream.java | 58 ------------------- .../export/PreferencesObjectInputStream.kt | 52 +++++++++++++++++ 2 files changed, 52 insertions(+), 58 deletions(-) delete mode 100644 app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.java create mode 100644 app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.kt diff --git a/app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.java b/app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.java deleted file mode 100644 index 0d11b0b61..000000000 --- a/app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.schabi.newpipe.settings.export; - -import java.io.IOException; -import java.io.InputStream; -import java.io.ObjectInputStream; -import java.io.ObjectStreamClass; -import java.util.Set; - -/** - * An {@link ObjectInputStream} that only allows preferences-related types to be deserialized, to - * prevent injections. The only allowed types are: all primitive types, all boxed primitive types, - * null, strings. HashMap, HashSet and arrays of previously defined types are also allowed. Sources: - * - * cmu.edu - * , - * - * OWASP cheatsheet - * , - * - * Apache's {@code ValidatingObjectInputStream} - * - */ -public class PreferencesObjectInputStream extends ObjectInputStream { - - /** - * Primitive types, strings and other built-in types do not pass through resolveClass() but - * instead have a custom encoding; see - * - * official docs. - */ - private static final Set CLASS_WHITELIST = Set.of( - "java.lang.Boolean", - "java.lang.Byte", - "java.lang.Character", - "java.lang.Short", - "java.lang.Integer", - "java.lang.Long", - "java.lang.Float", - "java.lang.Double", - "java.lang.Void", - "java.util.HashMap", - "java.util.HashSet" - ); - - public PreferencesObjectInputStream(final InputStream in) throws IOException { - super(in); - } - - @Override - protected Class resolveClass(final ObjectStreamClass desc) - throws ClassNotFoundException, IOException { - if (CLASS_WHITELIST.contains(desc.getName())) { - return super.resolveClass(desc); - } else { - throw new ClassNotFoundException("Class not allowed: " + desc.getName()); - } - } -} diff --git a/app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.kt b/app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.kt new file mode 100644 index 000000000..5f564a7a4 --- /dev/null +++ b/app/src/main/java/org/schabi/newpipe/settings/export/PreferencesObjectInputStream.kt @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: 2024-2026 NewPipe contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +package org.schabi.newpipe.settings.export + +import java.io.IOException +import java.io.InputStream +import java.io.ObjectInputStream +import java.io.ObjectStreamClass + +/** + * An [ObjectInputStream] that only allows preferences-related types to be deserialized, to + * prevent injections. The only allowed types are: all primitive types, all boxed primitive types, + * null, strings. HashMap, HashSet and arrays of previously defined types are also allowed. Sources: + * [cmu.edu](https://wiki.sei.cmu.edu/confluence/display/java/SER00-J.+Enable+serialization+compatibility+during+class+evolution) * , + * [OWASP cheatsheet](https://cheatsheetseries.owasp.org/cheatsheets/Deserialization_Cheat_Sheet.html#harden-your-own-javaioobjectinputstream) * , + * [Apache's `ValidatingObjectInputStream`](https://commons.apache.org/proper/commons-io/apidocs/src-html/org/apache/commons/io/serialization/ValidatingObjectInputStream.html#line-118) * + */ +class PreferencesObjectInputStream(stream: InputStream) : ObjectInputStream(stream) { + @Throws(ClassNotFoundException::class, IOException::class) + override fun resolveClass(desc: ObjectStreamClass): Class<*> { + if (desc.name in CLASS_WHITELIST) { + return super.resolveClass(desc) + } else { + throw ClassNotFoundException("Class not allowed: $desc.name") + } + } + + companion object { + /** + * Primitive types, strings and other built-in types do not pass through resolveClass() but + * instead have a custom encoding; see + * [ + * official docs](https://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html#10152). + */ + private val CLASS_WHITELIST = setOf( + "java.lang.Boolean", + "java.lang.Byte", + "java.lang.Character", + "java.lang.Short", + "java.lang.Integer", + "java.lang.Long", + "java.lang.Float", + "java.lang.Double", + "java.lang.Void", + "java.util.HashMap", + "java.util.HashSet" + ) + } +}