fix(Spotify): Fix Hide Create button and Sanitize sharing links for older but supported app targets (#5159)

This commit is contained in:
Nuckyz
2025-06-11 17:20:19 -03:00
committed by GitHub
parent c0c56fef23
commit 55401368b8
4 changed files with 45 additions and 17 deletions

View File

@@ -37,20 +37,24 @@ public final class HideCreateButtonPatch {
return null;
}
String stringifiedNavigationBarItem = navigationBarItem.toString();
try {
String stringifiedNavigationBarItem = navigationBarItem.toString();
for (ComponentFilter componentFilter : CREATE_BUTTON_COMPONENT_FILTERS) {
if (componentFilter.filterUnavailable()) {
Logger.printInfo(() -> "returnNullIfIsCreateButton: Filter " +
componentFilter.getFilterRepresentation() + " not available, skipping");
continue;
}
for (ComponentFilter componentFilter : CREATE_BUTTON_COMPONENT_FILTERS) {
if (componentFilter.filterUnavailable()) {
Logger.printInfo(() -> "returnNullIfIsCreateButton: Filter " +
componentFilter.getFilterRepresentation() + " not available, skipping");
continue;
}
if (stringifiedNavigationBarItem.contains(componentFilter.getFilterValue())) {
Logger.printInfo(() -> "Hiding Create button because the navigation bar item " + navigationBarItem +
" matched the filter " + componentFilter.getFilterRepresentation());
return null;
if (stringifiedNavigationBarItem.contains(componentFilter.getFilterValue())) {
Logger.printInfo(() -> "Hiding Create button because the navigation bar item " +
navigationBarItem + " matched the filter " + componentFilter.getFilterRepresentation());
return null;
}
}
} catch (Exception ex) {
Logger.printException(() -> "returnNullIfIsCreateButton failure", ex);
}
return navigationBarItem;

View File

@@ -72,7 +72,7 @@ val hideCreateButtonPatch = bytecodePatch(
if (oldNavigationBarAddItemMethod != null) {
// In case an older version of the app is being patched, hook the old method which adds navigation bar items.
// Return null early if the navigation bar item title resource id is the old Create button title resource id.
// Return early if the navigation bar item title resource id is the old Create button title resource id.
oldNavigationBarAddItemFingerprint.methodOrNull?.apply {
val getNavigationBarItemTitleStringIndex = indexOfFirstInstructionOrThrow {
val reference = getReference<MethodReference>()
@@ -89,6 +89,16 @@ val hideCreateButtonPatch = bytecodePatch(
val isOldCreateButtonDescriptor =
"$EXTENSION_CLASS_DESCRIPTOR->isOldCreateButton(I)Z"
val returnEarlyInstruction = if (returnType == "V") {
// In older implementations the method return value is void.
"return-void"
} else {
// In newer implementations
// return null because the method return value is a BottomNavigationItemView.
"const/4 v0, 0\n" +
"return-object v0"
}
addInstructionsWithLabels(
0,
"""
@@ -98,9 +108,7 @@ val hideCreateButtonPatch = bytecodePatch(
# If this navigation bar item is not the Create button, jump to the normal method logic.
if-eqz v0, :normal-method-logic
# Return null early because this method return value is a BottomNavigationItemView.
const/4 v0, 0
return-object v0
$returnEarlyInstruction
""",
ExternalLabel("normal-method-logic", firstInstruction)
)

View File

@@ -3,6 +3,7 @@ package app.revanced.patches.spotify.misc.privacy
import app.revanced.patcher.fingerprint
import app.revanced.util.literal
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.Opcode
internal val shareCopyUrlFingerprint = fingerprint {
returns("Ljava/lang/Object;")
@@ -23,9 +24,15 @@ internal val shareCopyUrlLegacyFingerprint = fingerprint {
}
internal val formatAndroidShareSheetUrlFingerprint = fingerprint {
accessFlags(AccessFlags.PUBLIC, AccessFlags.STATIC)
returns("Ljava/lang/String;")
parameters("L", "Ljava/lang/String;")
opcodes(
Opcode.GOTO,
Opcode.IF_EQZ,
Opcode.INVOKE_STATIC,
Opcode.MOVE_RESULT_OBJECT,
Opcode.RETURN_OBJECT
)
literal {
'\n'.code.toLong()
}

View File

@@ -8,6 +8,7 @@ import app.revanced.patches.spotify.misc.extension.sharedExtensionPatch
import app.revanced.patches.spotify.shared.IS_SPOTIFY_LEGACY_APP_TARGET
import app.revanced.util.getReference
import app.revanced.util.indexOfFirstInstructionOrThrow
import com.android.tools.smali.dexlib2.AccessFlags
import com.android.tools.smali.dexlib2.iface.instruction.FiveRegisterInstruction
import com.android.tools.smali.dexlib2.iface.reference.MethodReference
@@ -56,7 +57,15 @@ val sanitizeSharingLinksPatch = bytecodePatch(
shareUrlParameter = "p2"
} else {
shareSheetFingerprint = formatAndroidShareSheetUrlFingerprint
shareUrlParameter = "p1"
val methodAccessFlags = formatAndroidShareSheetUrlFingerprint.originalMethod.accessFlags
shareUrlParameter = if (AccessFlags.STATIC.isSet(methodAccessFlags)) {
// In newer implementations the method is static, so p0 is not `this`.
"p1"
} else {
// In older implementations the method is not static, making it so p0 is `this`.
// For that reason, add one to the parameter register.
"p2"
}
}
shareSheetFingerprint.method.addInstructions(