🐛 Remove backlinks from keys (thx, TheSeeker!)
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 26 Jun 2019 05:41:25 +0000 (07:41 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 26 Jun 2019 05:41:25 +0000 (07:41 +0200)
src/main/kotlin/net/pterodactylus/sone/text/SoneTextParser.kt
src/test/kotlin/net/pterodactylus/sone/text/SoneTextParserTest.kt

index ad9bca4..554c19b 100644 (file)
@@ -1,22 +1,14 @@
 package net.pterodactylus.sone.text
 
-import freenet.keys.FreenetURI
-import freenet.support.Base64
-import net.pterodactylus.sone.data.Sone
-import net.pterodactylus.sone.data.impl.IdOnlySone
-import net.pterodactylus.sone.database.PostProvider
-import net.pterodactylus.sone.database.SoneProvider
-import net.pterodactylus.sone.text.LinkType.CHK
-import net.pterodactylus.sone.text.LinkType.FREEMAIL
-import net.pterodactylus.sone.text.LinkType.HTTP
-import net.pterodactylus.sone.text.LinkType.HTTPS
-import net.pterodactylus.sone.text.LinkType.KSK
-import net.pterodactylus.sone.text.LinkType.POST
-import net.pterodactylus.sone.text.LinkType.SONE
-import net.pterodactylus.sone.text.LinkType.SSK
+import freenet.keys.*
+import freenet.support.*
+import net.pterodactylus.sone.data.*
+import net.pterodactylus.sone.data.impl.*
+import net.pterodactylus.sone.database.*
+import net.pterodactylus.sone.text.LinkType.*
 import net.pterodactylus.sone.text.LinkType.USK
-import org.bitpedia.util.Base32
-import java.net.MalformedURLException
+import org.bitpedia.util.*
+import java.net.*
 import javax.inject.*
 
 /**
@@ -50,33 +42,39 @@ class SoneTextParser @Inject constructor(private val soneProvider: SoneProvider?
                                                        }
                        }.map { it.first }.toList()
 
+       private val NextLink.linkWithoutBacklink: String
+               get() {
+                       val backlink = link.indexOf("/../")
+                       val query = link.indexOf("?")
+                       return if ((backlink > -1) && ((query == -1) || (query > -1) && (backlink < query)))
+                               link.substring(0, backlink)
+                       else
+                               link
+               }
+
        private fun NextLink.toPart(context: SoneTextParserContext?) = when (linkType) {
                KSK, CHK -> try {
-                       FreenetURI(link).let { freenetUri ->
+                       FreenetURI(linkWithoutBacklink).let { freenetUri ->
                                FreenetLinkPart(
-                                               link,
-                                               if (freenetUri.isKSK) {
-                                                       freenetUri.guessableKey
-                                               } else {
-                                                       freenetUri.metaString ?: freenetUri.docName ?: link.substring(0, 9)
-                                               },
-                                               link.split('?').first()
+                                               linkWithoutBacklink,
+                                               freenetUri.allMetaStrings?.lastOrNull { it != "" } ?: freenetUri.docName ?: linkWithoutBacklink.substring(0, 9),
+                                               linkWithoutBacklink.split('?').first()
                                )
                        }
                } catch (e: MalformedURLException) {
-                       PlainTextPart(link)
+                       PlainTextPart(linkWithoutBacklink)
                }
                SSK, USK ->
                        try {
-                               FreenetURI(link).let { uri ->
+                               FreenetURI(linkWithoutBacklink).let { uri ->
                                        uri.allMetaStrings
-                                                       ?.takeIf { (it.size > 1) || ((it.size == 1) && (it.single() != ""))}
+                                                       ?.takeIf { (it.size > 1) || ((it.size == 1) && (it.single() != "")) }
                                                        ?.lastOrNull()
                                                        ?: uri.docName
                                                        ?: "${uri.keyType}@${uri.routingKey.freenetBase64}"
-                               }.let { FreenetLinkPart(link.removeSuffix("/"), it, trusted = context?.routingKey?.contentEquals(FreenetURI(link).routingKey) == true) }
+                               }.let { FreenetLinkPart(linkWithoutBacklink.removeSuffix("/"), it, trusted = context?.routingKey?.contentEquals(FreenetURI(linkWithoutBacklink).routingKey) == true) }
                        } catch (e: MalformedURLException) {
-                               PlainTextPart(link)
+                               PlainTextPart(linkWithoutBacklink)
                        }
                SONE -> link.substring(7).let { SonePart(soneProvider?.getSone(it) ?: IdOnlySone(it)) }
                POST -> postProvider?.getPost(link.substring(7))?.let { PostPart(it) } ?: PlainTextPart(link)
index a3fe706..ff0572c 100644 (file)
@@ -244,6 +244,13 @@ class SoneTextParserTest {
        }
 
        @Test
+       fun `usk links with backlinks is parsed correctly`() {
+               val context = SoneTextParserContext(IdOnlySone("qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU"))
+               val parts = soneTextParser.parse("USK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test/0/../../../USK@nwa8lHa271k2QvJ8aa0Ov7IHAV-DFOCFgmDt3X6BpCI,DuQSUZiI~agF8c-6tjsFFGuZ8eICrzWCILB60nT8KKo,AQACAAE/sone/78/", context)
+               assertThat("Part Text", convertText(parts), equalTo("[USK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test/0|trusted|USK@qM1nmgU-YUnIttmEhqjTl7ifAF3Z6o~5EPwQW03uEQU,aztSUkT-VT1dWvfSUt9YpfyW~Flmf5yXpBnIE~v8sAg,AAMC--8/test/0|test]"))
+       }
+
+       @Test
        fun `test basic ksk links`() {
                val parts: Iterable<Part> = soneTextParser.parse("KSK@gpl.txt", null)
                assertThat("Part Text", convertText(parts, FreenetLinkPart::class.java), equalTo("[KSK@gpl.txt|KSK@gpl.txt|gpl.txt]"))
@@ -262,6 +269,12 @@ class SoneTextParserTest {
        }
 
        @Test
+       fun `ksk links with backlinks are parsed correctly`() {
+               val parts = soneTextParser.parse("KSK@gallery/../Sone/imageBrowser.html?album=30c930ee-97cd-11e9-bd44-f3e595768b77", null)
+               assertThat("Part Text", convertText(parts, FreenetLinkPart::class.java), equalTo("[KSK@gallery|KSK@gallery|gallery]"))
+       }
+
+       @Test
        fun `test empty lines and sone links`() {
                val soneTextParser = SoneTextParser(TestSoneProvider(), null)