From d8fdb3b818c6ec8a928a274b4bee527dbf30eed6 Mon Sep 17 00:00:00 2001 From: Javi Rueda Date: Fri, 19 Mar 2021 11:00:24 +0100 Subject: [PATCH] Decode and encode urls with non-authorized characters (#1174) * Decode URL encoded links and unit test it * Encode UTF8 characters on LBRY.TV links and unit test it --- .../java/io/lbry/browser/utils/LbryUri.java | 39 ++++++++++++-- .../io/lbry/browser/utils/LbryUriTest.java | 52 +++++++++++++++++++ 2 files changed, 87 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/io/lbry/browser/utils/LbryUri.java b/app/src/main/java/io/lbry/browser/utils/LbryUri.java index d903cdb..a55dd0f 100644 --- a/app/src/main/java/io/lbry/browser/utils/LbryUri.java +++ b/app/src/main/java/io/lbry/browser/utils/LbryUri.java @@ -1,5 +1,8 @@ package io.lbry.browser.utils; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -8,6 +11,8 @@ import java.util.regex.Pattern; import io.lbry.browser.exceptions.LbryUriException; import lombok.Data; +import static org.apache.commons.codec.CharEncoding.UTF_8; + @Data public class LbryUri { public static final String LBRY_TV_BASE_URL = "https://lbry.tv/"; @@ -117,10 +122,17 @@ public class LbryUri { } } - String streamOrChannelName = components.get(2); + String streamOrChannelName = null; + String possibleStreamName = null; + try { + // Using java.net.URLDecoder to be able to quickly unit test + streamOrChannelName = URLDecoder.decode(components.get(2), UTF_8); + possibleStreamName = URLDecoder.decode(components.get(6), UTF_8); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } String primaryModSeparator = components.get(3); String primaryModValue = components.get(4); - String possibleStreamName = components.get(6); String secondaryModSeparator = components.get(7); String secondaryModValue = components.get(8); @@ -188,7 +200,18 @@ public class LbryUri { if (channelName != null) { formattedChannelName = channelName.startsWith("@") ? channelName : String.format("@%s", channelName); } - String primaryClaimName = claimName; + String primaryClaimName = null; + + if (protocol.equals(LBRY_TV_BASE_URL) && Helper.isNullOrEmpty(formattedChannelName)) { + try { + primaryClaimName = URLEncoder.encode(claimName, UTF_8); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } else { + primaryClaimName = claimName; + } + if (Helper.isNullOrEmpty(primaryClaimName)) { primaryClaimName = contentName; } @@ -218,7 +241,15 @@ public class LbryUri { secondaryClaimName = contentName; } if (Helper.isNullOrEmpty(secondaryClaimName)) { - secondaryClaimName = !Helper.isNullOrEmpty(formattedChannelName) ? streamName : null; + if (protocol.equals(LBRY_TV_BASE_URL)) { + try { + secondaryClaimName = !Helper.isNullOrEmpty(formattedChannelName) ? URLEncoder.encode(streamName, UTF_8) : null; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } else { + secondaryClaimName = !Helper.isNullOrEmpty(formattedChannelName) ? streamName : null; + } } String secondaryClaimId = !Helper.isNullOrEmpty(secondaryClaimName) ? streamClaimId : null; diff --git a/app/src/test/java/io/lbry/browser/utils/LbryUriTest.java b/app/src/test/java/io/lbry/browser/utils/LbryUriTest.java index 1a5730e..7dfa46a 100644 --- a/app/src/test/java/io/lbry/browser/utils/LbryUriTest.java +++ b/app/src/test/java/io/lbry/browser/utils/LbryUriTest.java @@ -113,6 +113,32 @@ public class LbryUriTest { assertEquals(expectedForChannel, obtained); } + @Test + public void parseLbryTvWithEncodedChars() { + LbryUri obtained = new LbryUri(); + + try { + obtained = LbryUri.parse("https://lbry.tv/@Content_I_Like:1/DR.-ASTRID-ST%C3%9CCKELBERGER:2",false); + } catch (LbryUriException e) { + e.printStackTrace(); + } + + expected = new LbryUri(); + expected.setChannelName("@Content_I_Like"); + expected.setStreamName("DR.-ASTRID-STÜCKELBERGER"); + + try { + LbryUri.UriModifier primaryMod = LbryUri.UriModifier.parse("#", "1"); + LbryUri.UriModifier secondaryMod = LbryUri.UriModifier.parse("#", "2"); + expected.setChannelClaimId(primaryMod.getClaimId()); + expected.setStreamClaimId(secondaryMod.getClaimId()); + } catch (LbryUriException e) { + e.printStackTrace(); + } + + assertEquals(expected, obtained); + } + @Test public void lbryToTvString() { LbryUri obtained = new LbryUri(); @@ -126,6 +152,32 @@ public class LbryUriTest { assertEquals("https://lbry.tv/@lbry:3f/lbryturns4:6", obtained.toTvString()); } + @Test + public void lbryToTvStringWithEncodedChars() { + LbryUri obtained = new LbryUri(); + + try { + obtained = LbryUri.parse("lbry://La-Peur,-Nos-Attentats,-c'est-VOTRE-Sécurité!-Les-Guignols#6",false); + } catch (LbryUriException e) { + e.printStackTrace(); + } + + assertEquals("https://lbry.tv/La-Peur%2C-Nos-Attentats%2C-c%27est-VOTRE-Se%CC%81curite%CC%81%21-Les-Guignols:6", obtained.toTvString()); + } + + @Test + public void lbryToTvStringWithChannelAndEncodedChars() { + LbryUri obtained = new LbryUri(); + + try { + obtained = LbryUri.parse("lbry://@test#1/La-Peur,-Nos-Attentats,-c'est-VOTRE-Sécurité!-Les-Guignols#6",false); + } catch (LbryUriException e) { + e.printStackTrace(); + } + + assertEquals("https://lbry.tv/@test:1/La-Peur%2C-Nos-Attentats%2C-c%27est-VOTRE-Se%CC%81curite%CC%81%21-Les-Guignols:6", obtained.toTvString()); + } + @NotNull private LbryUri sinthesizeExpected() { LbryUri expectedForChannel = new LbryUri();