Skip to content

Commit 963a4ef

Browse files
brossshoSumAtrIXLisoUseInAIKyrios
authored
feat(Instagram): Add Sanitize sharing links patch (#5986)
Co-authored-by: oSumAtrIX <[email protected]> Co-authored-by: LisoUseInAIKyrios <[email protected]>
1 parent 0acba30 commit 963a4ef

File tree

9 files changed

+164
-37
lines changed

9 files changed

+164
-37
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package app.revanced.extension.instagram.misc.privacy;
2+
3+
import app.revanced.extension.shared.privacy.LinkSanitizer;
4+
5+
@SuppressWarnings("unused")
6+
public final class SanitizeSharingLinksPatch {
7+
private static final LinkSanitizer sanitizer = new LinkSanitizer("igsh");
8+
9+
/**
10+
* Injection point.
11+
*/
12+
public static String sanitizeSharingLink(String url) {
13+
return sanitizer.sanitizeUrlString(url);
14+
}
15+
}

extensions/shared/library/src/main/java/app/revanced/extension/shared/patches/SanitizeSharingLinksPatch.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,25 @@
11
package app.revanced.extension.shared.patches;
22

3+
import app.revanced.extension.shared.privacy.LinkSanitizer;
34
import app.revanced.extension.shared.settings.BaseSettings;
45

56
/**
67
* YouTube and YouTube Music.
78
*/
89
@SuppressWarnings("unused")
910
public final class SanitizeSharingLinksPatch {
10-
private static final String NEW_TRACKING_PARAMETER_REGEX = ".si=.+";
11-
private static final String OLD_TRACKING_PARAMETER_REGEX = ".feature=.+";
11+
12+
private static final LinkSanitizer sanitizer = new LinkSanitizer(
13+
"si",
14+
"feature" // Old tracking parameter name, and may be obsolete.
15+
);
1216

1317
/**
1418
* Injection point.
1519
*/
1620
public static String sanitize(String url) {
1721
if (BaseSettings.SANITIZE_SHARED_LINKS.get()) {
18-
url = url
19-
.replaceAll(NEW_TRACKING_PARAMETER_REGEX, "")
20-
.replaceAll(OLD_TRACKING_PARAMETER_REGEX, "");
22+
url = sanitizer.sanitizeUrlString(url);
2123
}
2224

2325
if (BaseSettings.REPLACE_MUSIC_LINKS_WITH_YOUTUBE.get()) {
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
package app.revanced.extension.shared.privacy;
2+
3+
import android.net.Uri;
4+
5+
import java.util.Collection;
6+
import java.util.List;
7+
import java.util.Set;
8+
9+
import app.revanced.extension.shared.Logger;
10+
11+
/**
12+
* Strips away specific parameters from URLs.
13+
*/
14+
public class LinkSanitizer {
15+
16+
private final Collection<String> parametersToRemove;
17+
18+
public LinkSanitizer(String ... parametersToRemove) {
19+
final int parameterCount = parametersToRemove.length;
20+
if (parameterCount == 0) {
21+
throw new IllegalArgumentException("No parameters specified");
22+
}
23+
24+
// List is faster if only checking a few parameters.
25+
this.parametersToRemove = parameterCount > 4
26+
? Set.of(parametersToRemove)
27+
: List.of(parametersToRemove);
28+
}
29+
30+
public String sanitizeUrlString(String url) {
31+
try {
32+
return sanitizeUri(Uri.parse(url)).toString();
33+
} catch (Exception ex) {
34+
Logger.printException(() -> "sanitizeUrlString failure: " + url, ex);
35+
return url;
36+
}
37+
}
38+
39+
public Uri sanitizeUri(Uri uri) {
40+
try {
41+
Uri.Builder builder = uri.buildUpon().clearQuery();
42+
43+
for (String paramName : uri.getQueryParameterNames()) {
44+
if (!parametersToRemove.contains(paramName)) {
45+
for (String value : uri.getQueryParameters(paramName)) {
46+
builder.appendQueryParameter(paramName, value);
47+
}
48+
}
49+
}
50+
51+
Uri sanitizedUrl = builder.build();
52+
Logger.printInfo(() -> "Sanitized url: " + uri + " to: " + sanitizedUrl);
53+
54+
return sanitizedUrl;
55+
} catch (Exception ex) {
56+
Logger.printException(() -> "sanitizeUri failure: " + uri, ex);
57+
return uri;
58+
}
59+
}
60+
}
Lines changed: 4 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,19 @@
11
package app.revanced.extension.spotify.misc.privacy;
22

3-
import android.net.Uri;
4-
5-
import java.util.List;
6-
7-
import app.revanced.extension.shared.Logger;
3+
import app.revanced.extension.shared.privacy.LinkSanitizer;
84

95
@SuppressWarnings("unused")
106
public final class SanitizeSharingLinksPatch {
117

12-
/**
13-
* Parameters that are considered undesirable and should be stripped away.
14-
*/
15-
private static final List<String> SHARE_PARAMETERS_TO_REMOVE = List.of(
8+
private static final LinkSanitizer sanitizer = new LinkSanitizer(
169
"si", // Share tracking parameter.
1710
"utm_source" // Share source, such as "copy-link".
1811
);
1912

2013
/**
2114
* Injection point.
2215
*/
23-
public static String sanitizeUrl(String url) {
24-
try {
25-
Uri uri = Uri.parse(url);
26-
Uri.Builder builder = uri.buildUpon().clearQuery();
27-
28-
for (String paramName : uri.getQueryParameterNames()) {
29-
if (!SHARE_PARAMETERS_TO_REMOVE.contains(paramName)) {
30-
for (String value : uri.getQueryParameters(paramName)) {
31-
builder.appendQueryParameter(paramName, value);
32-
}
33-
}
34-
}
35-
36-
String sanitizedUrl = builder.build().toString();
37-
Logger.printInfo(() -> "Sanitized url " + url + " to " + sanitizedUrl);
38-
return sanitizedUrl;
39-
} catch (Exception ex) {
40-
Logger.printException(() -> "sanitizeUrl failure with " + url, ex);
41-
return url;
42-
}
16+
public static String sanitizeSharingLink(String url) {
17+
return sanitizer.sanitizeUrlString(url);
4318
}
4419
}

patches/api/patches.api

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ public final class app/revanced/patches/instagram/misc/links/OpenLinksExternally
288288
public static final fun getOpenLinksExternallyPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
289289
}
290290

291+
public final class app/revanced/patches/instagram/misc/privacy/SanitizeSharingLinksPatchKt {
292+
public static final fun getSanitizeSharingLinksPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
293+
}
294+
291295
public final class app/revanced/patches/instagram/misc/signature/SignatureCheckPatchKt {
292296
public static final fun getSignatureCheckPatch ()Lapp/revanced/patcher/patch/BytecodePatch;
293297
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package app.revanced.patches.instagram.misc.privacy
2+
3+
import app.revanced.patcher.fingerprint
4+
5+
internal val permalinkResponseJsonParserFingerprint = fingerprint {
6+
strings("permalink", "PermalinkResponse")
7+
custom { method, _ -> method.name == "parseFromJson" }
8+
}
9+
10+
internal val storyUrlResponseJsonParserFingerprint = fingerprint {
11+
strings("story_item_to_share_url", "StoryItemUrlResponse")
12+
custom { method, _ -> method.name == "parseFromJson" }
13+
}
14+
15+
internal val profileUrlResponseJsonParserFingerprint = fingerprint {
16+
strings("profile_to_share_url", "ProfileUrlResponse")
17+
custom { method, _ -> method.name == "parseFromJson" }
18+
}
19+
20+
internal val liveUrlResponseJsonParserFingerprint = fingerprint {
21+
strings("live_to_share_url", "LiveItemLinkUrlResponse")
22+
custom { method, _ -> method.name == "parseFromJson" }
23+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package app.revanced.patches.instagram.misc.privacy
2+
3+
import app.revanced.patcher.extensions.InstructionExtensions.addInstructions
4+
import app.revanced.patcher.extensions.InstructionExtensions.getInstruction
5+
import app.revanced.patcher.patch.bytecodePatch
6+
import app.revanced.patches.instagram.misc.extension.sharedExtensionPatch
7+
import app.revanced.util.indexOfFirstInstructionOrThrow
8+
import com.android.tools.smali.dexlib2.Opcode
9+
import com.android.tools.smali.dexlib2.iface.instruction.TwoRegisterInstruction
10+
11+
private const val EXTENSION_CLASS_DESCRIPTOR =
12+
"Lapp/revanced/extension/instagram/misc/privacy/SanitizeSharingLinksPatch;"
13+
14+
@Suppress("unused")
15+
val sanitizeSharingLinksPatch = bytecodePatch(
16+
name = "Sanitize sharing links",
17+
description = "Removes the tracking query parameters from shared links.",
18+
) {
19+
compatibleWith("com.instagram.android")
20+
21+
dependsOn(sharedExtensionPatch)
22+
23+
execute {
24+
arrayOf(
25+
permalinkResponseJsonParserFingerprint,
26+
storyUrlResponseJsonParserFingerprint,
27+
profileUrlResponseJsonParserFingerprint,
28+
liveUrlResponseJsonParserFingerprint
29+
).forEach { fingerprint ->
30+
fingerprint.method.apply {
31+
val putSharingUrlIndex = indexOfFirstInstructionOrThrow(
32+
fingerprint.stringMatches!!.first().index,
33+
Opcode.IPUT_OBJECT
34+
)
35+
36+
val sharingUrlRegister = getInstruction<TwoRegisterInstruction>(putSharingUrlIndex).registerA
37+
38+
addInstructions(
39+
putSharingUrlIndex,
40+
"""
41+
invoke-static { v$sharingUrlRegister }, $EXTENSION_CLASS_DESCRIPTOR->sanitizeSharingLink(Ljava/lang/String;)Ljava/lang/String;
42+
move-result-object v$sharingUrlRegister
43+
"""
44+
)
45+
}
46+
}
47+
}
48+
}

patches/src/main/kotlin/app/revanced/patches/reddit/misc/tracking/url/SanitizeUrlQueryPatch.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import app.revanced.patcher.patch.bytecodePatch
66
@Suppress("unused")
77
val sanitizeUrlQueryPatch = bytecodePatch(
88
name = "Sanitize sharing links",
9-
description = "Removes (tracking) query parameters from the URLs when sharing links.",
9+
description = "Removes the tracking query parameters from shared links.",
1010
) {
1111
compatibleWith("com.reddit.frontpage")
1212

patches/src/main/kotlin/app/revanced/patches/spotify/misc/privacy/SanitizeSharingLinksPatch.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ private const val EXTENSION_CLASS_DESCRIPTOR =
1616
@Suppress("unused")
1717
val sanitizeSharingLinksPatch = bytecodePatch(
1818
name = "Sanitize sharing links",
19-
description = "Removes the tracking query parameters from links before they are shared.",
19+
description = "Removes the tracking query parameters from shared links.",
2020
) {
2121
compatibleWith("com.spotify.music")
2222

2323
dependsOn(sharedExtensionPatch)
2424

2525
execute {
2626
val extensionMethodDescriptor = "$EXTENSION_CLASS_DESCRIPTOR->" +
27-
"sanitizeUrl(Ljava/lang/String;)Ljava/lang/String;"
27+
"sanitizeSharingLink(Ljava/lang/String;)Ljava/lang/String;"
2828

2929
val copyFingerprint = if (shareCopyUrlFingerprint.originalMethodOrNull != null) {
3030
shareCopyUrlFingerprint

0 commit comments

Comments
 (0)