From 675a2c42097aa2ad20303f2288a0d7f96c6d362e Mon Sep 17 00:00:00 2001 From: LisoUseInAIKyrios <118716522+LisoUseInAIKyrios@users.noreply.github.com> Date: Sat, 8 Nov 2025 18:34:00 +0200 Subject: [PATCH] add fix content provider patch --- .../patches/FixContentProviderPatch.java | 24 ++++++++++++ .../youtube/misc/debugging/Fingerprints.kt | 38 ------------------- .../FIxContentProviderPatch.kt | 35 +++++++++++++++++ .../misc/fix/contentprovider/Fingerprints.kt | 20 ++++++++++ .../FIxPlaybackSpeedWhilePlayingPatch.kt | 1 - .../youtube/misc/settings/SettingsPatch.kt | 2 + 6 files changed, 81 insertions(+), 39 deletions(-) create mode 100644 extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/FixContentProviderPatch.java delete mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt create mode 100644 patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt diff --git a/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/FixContentProviderPatch.java b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/FixContentProviderPatch.java new file mode 100644 index 000000000..e3bf0478a --- /dev/null +++ b/extensions/youtube/src/main/java/app/revanced/extension/youtube/patches/FixContentProviderPatch.java @@ -0,0 +1,24 @@ +package app.revanced.extension.youtube.patches; + +import java.util.Map; + +import app.revanced.extension.shared.Logger; + +@SuppressWarnings("unused") +public class FixContentProviderPatch { + + /** + * Injection point. + */ + public static void removeNullMapEntries(Map map) { + map.entrySet().removeIf(entry -> { + Object value = entry.getValue(); + if (value == null) { + Logger.printDebug(() -> "Removing content provider key with null value: " + entry.getKey()); + return true; + } + return false; + }); + } +} + diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt deleted file mode 100644 index 8fb89cdda..000000000 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/debugging/Fingerprints.kt +++ /dev/null @@ -1,38 +0,0 @@ -package app.revanced.patches.youtube.misc.debugging - -import app.revanced.patcher.fingerprint -import app.revanced.patcher.string -import com.android.tools.smali.dexlib2.AccessFlags - -internal val experimentalFeatureFlagParentFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) - returns("L") - parameters("L", "J", "[B") - instructions( - string("Unable to parse proto typed experiment flag: ") - ) -} - -internal val experimentalBooleanFeatureFlagFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC) - returns("Z") - parameters("L", "J", "Z") -} - -internal val experimentalDoubleFeatureFlagFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("D") - parameters("J", "D") -} - -internal val experimentalLongFeatureFlagFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("J") - parameters("J", "J") -} - -internal val experimentalStringFeatureFlagFingerprint = fingerprint { - accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) - returns("Ljava/lang/String;") - parameters("J", "Ljava/lang/String;") -} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt new file mode 100644 index 000000000..de4e9a2b6 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/FIxContentProviderPatch.kt @@ -0,0 +1,35 @@ +package app.revanced.patches.youtube.misc.fix.contentprovider + +import app.revanced.patcher.extensions.InstructionExtensions.addInstruction +import app.revanced.patcher.extensions.InstructionExtensions.getInstruction +import app.revanced.patcher.patch.bytecodePatch +import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction + +private const val EXTENSION_CLASS_DESCRIPTOR = + "Lapp/revanced/extension/youtube/patches/FixContentProviderPatch;" + +/** + * Fixes crashing for some users with a beta release where the YouTube content provider uses null map values. + * It unknown if this crash can happen on stable releases. + */ +internal val fixContentProviderPatch = bytecodePatch{ + dependsOn( + sharedExtensionPatch + ) + + execute { + unstableContentProviderFingerprint.let { + val insertIndex = it.instructionMatches.first().index + + it.method.apply { + val register = getInstruction(insertIndex).registerD + + it.method.addInstruction( + insertIndex, + "invoke-static { v$register }, $EXTENSION_CLASS_DESCRIPTOR->removeNullMapEntries(Ljava/util/Map;)V" + ) + } + } + } +} \ No newline at end of file diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt new file mode 100644 index 000000000..7e3ab83c2 --- /dev/null +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/contentprovider/Fingerprints.kt @@ -0,0 +1,20 @@ +package app.revanced.patches.youtube.misc.fix.contentprovider + +import app.revanced.patcher.fingerprint +import app.revanced.patcher.methodCall +import app.revanced.patcher.string +import com.android.tools.smali.dexlib2.AccessFlags + +internal val unstableContentProviderFingerprint = fingerprint { + accessFlags(AccessFlags.PUBLIC, AccessFlags.FINAL) + returns("V") + parameters("Landroid/content/ContentResolver;", "[Ljava/lang/String;") + instructions( + // Early targets use HashMap and later targets use ConcurrentMap. + methodCall( + name = "putAll", + parameters = listOf("Ljava/util/Map;") + ), + string("ContentProvider query returned null cursor") + ) +} diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt index b63eec794..f97139e40 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/fix/playbackspeed/FIxPlaybackSpeedWhilePlayingPatch.kt @@ -29,7 +29,6 @@ private const val EXTENSION_CLASS_DESCRIPTOR = * 6. Resume the video * 7. Playback speed will incorrectly change to 1.0x. */ -@Suppress("unused") val fixPlaybackSpeedWhilePlayingPatch = bytecodePatch{ dependsOn( sharedExtensionPatch, diff --git a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt index 7f109d54b..f59533a42 100644 --- a/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt +++ b/patches/src/main/kotlin/app/revanced/patches/youtube/misc/settings/SettingsPatch.kt @@ -26,6 +26,7 @@ import app.revanced.patches.shared.misc.settings.preference.TextPreference import app.revanced.patches.shared.misc.settings.settingsPatch import app.revanced.patches.youtube.misc.check.checkEnvironmentPatch import app.revanced.patches.youtube.misc.extension.sharedExtensionPatch +import app.revanced.patches.youtube.misc.fix.contentprovider.fixContentProviderPatch import app.revanced.patches.youtube.misc.fix.playbackspeed.fixPlaybackSpeedWhilePlayingPatch import app.revanced.patches.youtube.misc.playservice.is_19_34_or_greater import app.revanced.patches.youtube.misc.playservice.is_20_31_or_greater @@ -177,6 +178,7 @@ val settingsPatch = bytecodePatch( addResourcesPatch, versionCheckPatch, fixPlaybackSpeedWhilePlayingPatch, + fixContentProviderPatch, // Currently there is no easy way to make a mandatory patch, // so for now this is a dependent of this patch. checkEnvironmentPatch,