mirror of
https://github.com/ReVanced/revanced-patches.git
synced 2025-05-10 20:55:38 +02:00
feat(Spotify): Add Sanitize sharing links
patch (#4829)
This commit is contained in:
parent
2793f00368
commit
2e3511d03c
5 changed files with 160 additions and 2 deletions
|
@ -0,0 +1,43 @@
|
||||||
|
package app.revanced.extension.spotify.misc.privacy;
|
||||||
|
|
||||||
|
import android.net.Uri;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.Logger;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public final class SanitizeSharingLinksPatch {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameters that are considered undesirable and should be stripped away.
|
||||||
|
*/
|
||||||
|
private static final List<String> SHARE_PARAMETERS_TO_REMOVE = List.of(
|
||||||
|
"si", // Share tracking parameter.
|
||||||
|
"utm_source" // Share source, such as "copy-link".
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Injection point.
|
||||||
|
*/
|
||||||
|
public static String sanitizeUrl(String url) {
|
||||||
|
try {
|
||||||
|
Uri uri = Uri.parse(url);
|
||||||
|
Uri.Builder builder = uri.buildUpon().clearQuery();
|
||||||
|
|
||||||
|
for (String paramName : uri.getQueryParameterNames()) {
|
||||||
|
if (!SHARE_PARAMETERS_TO_REMOVE.contains(paramName)) {
|
||||||
|
for (String value : uri.getQueryParameters(paramName)) {
|
||||||
|
builder.appendQueryParameter(paramName, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.build().toString();
|
||||||
|
} catch (Exception ex) {
|
||||||
|
Logger.printException(() -> "sanitizeUrl failure", ex);
|
||||||
|
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -852,6 +852,10 @@ public final class app/revanced/patches/spotify/misc/fix/SpoofSignaturePatchKt {
|
||||||
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getSpoofSignaturePatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class app/revanced/patches/spotify/misc/privacy/SanitizeSharingLinksPatchKt {
|
||||||
|
public static final fun getSanitizeSharingLinksPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
|
}
|
||||||
|
|
||||||
public final class app/revanced/patches/spotify/navbar/PremiumNavbarTabPatchKt {
|
public final class app/revanced/patches/spotify/navbar/PremiumNavbarTabPatchKt {
|
||||||
public static final fun getPremiumNavbarTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
public static final fun getPremiumNavbarTabPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import app.revanced.patcher.extensions.InstructionExtensions.removeInstruction
|
||||||
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
import app.revanced.patcher.extensions.InstructionExtensions.replaceInstruction
|
||||||
import app.revanced.patcher.fingerprint
|
import app.revanced.patcher.fingerprint
|
||||||
import app.revanced.patcher.patch.bytecodePatch
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
import app.revanced.patches.spotify.misc.check.checkEnvironmentPatch
|
|
||||||
import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET
|
import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET
|
||||||
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||||
import app.revanced.util.getReference
|
import app.revanced.util.getReference
|
||||||
|
@ -72,9 +71,10 @@ val unlockPremiumPatch = bytecodePatch(
|
||||||
|
|
||||||
|
|
||||||
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
||||||
return@execute Logger.getLogger(this::class.java.name).warning(
|
Logger.getLogger(this::class.java.name).warning(
|
||||||
"Patching a legacy Spotify version. Patch functionality may be limited."
|
"Patching a legacy Spotify version. Patch functionality may be limited."
|
||||||
)
|
)
|
||||||
|
return@execute
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package app.revanced.patches.spotify.misc.privacy
|
||||||
|
|
||||||
|
import app.revanced.patcher.fingerprint
|
||||||
|
import app.revanced.util.literal
|
||||||
|
import com.android.tools.smali.dexlib2.AccessFlags
|
||||||
|
|
||||||
|
internal val shareCopyUrlFingerprint = fingerprint {
|
||||||
|
returns("Ljava/lang/Object;")
|
||||||
|
parameters("Ljava/lang/Object;")
|
||||||
|
strings("clipboard", "Spotify Link")
|
||||||
|
custom { method, _ ->
|
||||||
|
method.name == "invokeSuspend"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val shareCopyUrlLegacyFingerprint = fingerprint {
|
||||||
|
returns("Ljava/lang/Object;")
|
||||||
|
parameters("Ljava/lang/Object;")
|
||||||
|
strings("clipboard", "createNewSession failed")
|
||||||
|
custom { method, _ ->
|
||||||
|
method.name == "apply"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val formatAndroidShareSheetUrlFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
|
||||||
|
returns("Ljava/lang/String;")
|
||||||
|
parameters("L", "Ljava/lang/String;")
|
||||||
|
literal {
|
||||||
|
'\n'.code.toLong()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal val formatAndroidShareSheetUrlLegacyFingerprint = fingerprint {
|
||||||
|
accessFlags(AccessFlags.PUBLIC)
|
||||||
|
returns("Ljava/lang/String;")
|
||||||
|
parameters("Lcom/spotify/share/social/sharedata/ShareData;", "Ljava/lang/String;")
|
||||||
|
literal {
|
||||||
|
'\n'.code.toLong()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package app.revanced.patches.spotify.misc.privacy
|
||||||
|
|
||||||
|
import app.revanced.patcher.Fingerprint
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
|
||||||
|
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
|
||||||
|
import app.revanced.patcher.patch.bytecodePatch
|
||||||
|
import app.revanced.patches.spotify.misc.extension.IS_SPOTIFY_LEGACY_APP_TARGET
|
||||||
|
import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
|
||||||
|
import app.revanced.util.getReference
|
||||||
|
import app.revanced.util.indexOfFirstInstructionOrThrow
|
||||||
|
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
|
||||||
|
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
|
||||||
|
|
||||||
|
private const val EXTENSION_CLASS_DESCRIPTOR =
|
||||||
|
"Lapp/revanced/extension/spotify/misc/privacy/SanitizeSharingLinksPatch;"
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
val sanitizeSharingLinksPatch = bytecodePatch(
|
||||||
|
name = "Sanitize sharing links",
|
||||||
|
description = "Removes the tracking query parameters from links before they are shared.",
|
||||||
|
) {
|
||||||
|
compatibleWith("com.spotify.music")
|
||||||
|
|
||||||
|
dependsOn(sharedExtensionPatch)
|
||||||
|
|
||||||
|
execute {
|
||||||
|
val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" +
|
||||||
|
"sanitizeUrl(Ljava/lang/String;)Ljava/lang/String;"
|
||||||
|
|
||||||
|
val copyFingerprint = if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
||||||
|
shareCopyUrlLegacyFingerprint
|
||||||
|
} else {
|
||||||
|
shareCopyUrlFingerprint
|
||||||
|
}
|
||||||
|
|
||||||
|
copyFingerprint.method.apply {
|
||||||
|
val newPlainTextInvokeIndex = indexOfFirstInstructionOrThrow {
|
||||||
|
getReference<MethodReference>()?.name == "newPlainText"
|
||||||
|
}
|
||||||
|
val register = getInstruction<FiveRegisterInstruction>(newPlainTextInvokeIndex).registerD
|
||||||
|
|
||||||
|
addInstructions(
|
||||||
|
newPlainTextInvokeIndex,
|
||||||
|
"""
|
||||||
|
invoke-static { v$register }, $extensionMethodDescriptor
|
||||||
|
move-result-object v$register
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Android native share sheet is used for all other quick share types (X, WhatsApp, etc).
|
||||||
|
val shareUrlParameter : String
|
||||||
|
val shareSheetFingerprint : Fingerprint
|
||||||
|
if (IS_SPOTIFY_LEGACY_APP_TARGET) {
|
||||||
|
shareSheetFingerprint = formatAndroidShareSheetUrlLegacyFingerprint
|
||||||
|
shareUrlParameter = "p2"
|
||||||
|
} else {
|
||||||
|
shareSheetFingerprint = formatAndroidShareSheetUrlFingerprint
|
||||||
|
shareUrlParameter = "p1"
|
||||||
|
}
|
||||||
|
|
||||||
|
shareSheetFingerprint.method.addInstructions(
|
||||||
|
0,
|
||||||
|
"""
|
||||||
|
invoke-static { $shareUrlParameter }, $extensionMethodDescriptor
|
||||||
|
move-result-object $shareUrlParameter
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue