From 7c631aacaade84634bc5680beedc64aef135a183 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Mon, 30 Dec 2024 13:14:27 +0800 Subject: [PATCH 1/5] Adds secrets --- .../Secrets/Sources/Secrets/SecretKey.swift | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 Modules/Secrets/Sources/Secrets/SecretKey.swift diff --git a/Modules/Secrets/Sources/Secrets/SecretKey.swift b/Modules/Secrets/Sources/Secrets/SecretKey.swift new file mode 100644 index 000000000..2dbed3009 --- /dev/null +++ b/Modules/Secrets/Sources/Secrets/SecretKey.swift @@ -0,0 +1,64 @@ +// Generated by SecretKey.swift.gyb +import Foundation + +public struct SecretKey { + + public static let mercuryClientID: String = { + let encoded: [UInt8] = [ + ] + + return decode(encoded) + }() + + public static let mercuryClientSecret: String = { + let encoded: [UInt8] = [ + ] + + return decode(encoded) + }() + + public static let feedlyClientID: String = { + let encoded: [UInt8] = [ + ] + + return decode(encoded) + }() + + public static let feedlyClientSecret: String = { + let encoded: [UInt8] = [ + ] + + return decode(encoded) + }() + + public static let inoreaderAppID: String = { + let encoded: [UInt8] = [ + ] + + return decode(encoded) + }() + + public static let inoreaderAppKey: String = { + let encoded: [UInt8] = [ + ] + + return decode(encoded) + }() +} + +private let salt: [UInt8] = [ + 0x90, 0x43, 0xe3, 0x10, 0x4a, 0x75, 0xdc, 0xe0, + 0x9b, 0x4c, 0xf0, 0xc0, 0x99, 0x22, 0x0a, 0x5d, + 0x50, 0xa8, 0xe4, 0x6c, 0x87, 0x95, 0x67, 0x87, + 0x0a, 0x07, 0xf8, 0x63, 0x90, 0xcf, 0x92, 0x91, + 0x4c, 0x80, 0x1c, 0xf5, 0xd5, 0xdd, 0x8a, 0x34, + 0xf2, 0xfd, 0xfb, 0x4c, 0x94, 0x9b, 0x36, 0x97, + 0x0d, 0x80, 0x2b, 0xfd, 0x9a, 0xaf, 0x83, 0x96, + 0x60, 0x1a, 0xae, 0xd8, 0xf5, 0xed, 0x1c, 0x1d, +] + +private func decode(_ encoded: [UInt8]) -> String { + String(decoding: encoded.enumerated().map { (offset, element) in + element ^ salt[offset % salt.count] + }, as: UTF8.self) +} From 6ac974db267f871f4d4a6afa2be5c0ca3816adae Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Tue, 31 Dec 2024 17:09:49 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=A9=B9=20Stop=20beehiv=20blog=20style?= =?UTF-8?q?=20slipping=20into=20summaries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RSCore/Sources/RSCore/Shared/String+RSCore.swift | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/RSCore/Sources/RSCore/Shared/String+RSCore.swift b/RSCore/Sources/RSCore/Shared/String+RSCore.swift index 612f4fe60..1c5add27b 100644 --- a/RSCore/Sources/RSCore/Shared/String+RSCore.swift +++ b/RSCore/Sources/RSCore/Shared/String+RSCore.swift @@ -195,7 +195,15 @@ public extension String { /// /// - Note: Doesn't work correctly with nested tags of the same name. private func removingTagAndContents(_ tag: String) -> String { - return self.replacingOccurrences(of: "<\(tag).+?", with: "", options: [.regularExpression, .caseInsensitive]) + let pattern = "<\(tag)>.*?<\\/\(tag)>" + if let regex = try? NSRegularExpression(pattern: pattern, options: [.dotMatchesLineSeparators, .caseInsensitive]) { + let range = NSRange(location: 0, length: self.utf16.count) + let modifiedString = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "") + return modifiedString + } else { + // If the above regex fails, fall back to the original method. + return self.replacingOccurrences(of: "<\(tag).+?", with: "", options: [.regularExpression, .caseInsensitive]) + } } /// Strips HTML from a string. From f966123402a1f5eba4ec60abc9f2c36131ae7b21 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Wed, 1 Jan 2025 07:56:48 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=F0=9F=94=A5=20Remove=20SecretKey.swift?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Likely need to add this to .gitignore. --- .gitignore | 1 + .../Secrets/Sources/Secrets/SecretKey.swift | 64 ------------------- 2 files changed, 1 insertion(+), 64 deletions(-) delete mode 100644 Modules/Secrets/Sources/Secrets/SecretKey.swift diff --git a/.gitignore b/.gitignore index aab97332a..272f953ef 100644 --- a/.gitignore +++ b/.gitignore @@ -74,3 +74,4 @@ fastlane/test_output /Frameworks/Secrets/Secrets.swift Secrets/Sources/Secrets/Secrets.swift *.py[cod] +/Modules/Secrets/Sources/Secrets/SecretKey.swift diff --git a/Modules/Secrets/Sources/Secrets/SecretKey.swift b/Modules/Secrets/Sources/Secrets/SecretKey.swift deleted file mode 100644 index 2dbed3009..000000000 --- a/Modules/Secrets/Sources/Secrets/SecretKey.swift +++ /dev/null @@ -1,64 +0,0 @@ -// Generated by SecretKey.swift.gyb -import Foundation - -public struct SecretKey { - - public static let mercuryClientID: String = { - let encoded: [UInt8] = [ - ] - - return decode(encoded) - }() - - public static let mercuryClientSecret: String = { - let encoded: [UInt8] = [ - ] - - return decode(encoded) - }() - - public static let feedlyClientID: String = { - let encoded: [UInt8] = [ - ] - - return decode(encoded) - }() - - public static let feedlyClientSecret: String = { - let encoded: [UInt8] = [ - ] - - return decode(encoded) - }() - - public static let inoreaderAppID: String = { - let encoded: [UInt8] = [ - ] - - return decode(encoded) - }() - - public static let inoreaderAppKey: String = { - let encoded: [UInt8] = [ - ] - - return decode(encoded) - }() -} - -private let salt: [UInt8] = [ - 0x90, 0x43, 0xe3, 0x10, 0x4a, 0x75, 0xdc, 0xe0, - 0x9b, 0x4c, 0xf0, 0xc0, 0x99, 0x22, 0x0a, 0x5d, - 0x50, 0xa8, 0xe4, 0x6c, 0x87, 0x95, 0x67, 0x87, - 0x0a, 0x07, 0xf8, 0x63, 0x90, 0xcf, 0x92, 0x91, - 0x4c, 0x80, 0x1c, 0xf5, 0xd5, 0xdd, 0x8a, 0x34, - 0xf2, 0xfd, 0xfb, 0x4c, 0x94, 0x9b, 0x36, 0x97, - 0x0d, 0x80, 0x2b, 0xfd, 0x9a, 0xaf, 0x83, 0x96, - 0x60, 0x1a, 0xae, 0xd8, 0xf5, 0xed, 0x1c, 0x1d, -] - -private func decode(_ encoded: [UInt8]) -> String { - String(decoding: encoded.enumerated().map { (offset, element) in - element ^ salt[offset % salt.count] - }, as: UTF8.self) -} From d2364ff660c41b10bdf00b4768b12c6dd40f8c10 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Wed, 1 Jan 2025 08:27:21 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=93=9D=20Adds=20code=20comments=20for?= =?UTF-8?q?=20the=20regex=20used.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- RSCore/Sources/RSCore/Shared/String+RSCore.swift | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/RSCore/Sources/RSCore/Shared/String+RSCore.swift b/RSCore/Sources/RSCore/Shared/String+RSCore.swift index 1c5add27b..9b4dc32cc 100644 --- a/RSCore/Sources/RSCore/Shared/String+RSCore.swift +++ b/RSCore/Sources/RSCore/Shared/String+RSCore.swift @@ -189,6 +189,22 @@ public extension String { /// Removes an HTML tag and everything between its start and end tags. /// + /// The regex pattern `.*?` explanation: + /// - `<` matches the literal `<` character. + /// - `tag` matches the literal parameter provided to the function, e.g., `style`. + /// - `>` matches the literal `>` character. + /// - `.*?` + /// - `.` matches _any_ character **except** a new line + /// - `*` will match zero or more of the preceeding character, in this case _any_ + /// character + /// - `?` switches the matching mode to [lazy](https://javascript.info/regexp-greedy-and-lazy) + /// so it will match as few as characters as possible before satisfying the rest of the pattern. + /// - `<` matches the literal `<` character. + /// - `/` matches the literal `/` character. + /// - `tag` matches the literal parameter provided to the function, e.g., `style` + /// - `>` matches the literal `>` character. + /// + /// /// - Parameter tag: The tag to remove. /// /// - Returns: A new copy of `self` with the tag removed. From 9b508e068b68536fe16de4e8ee11ba82855494f6 Mon Sep 17 00:00:00 2001 From: Stuart Breckenridge Date: Wed, 1 Jan 2025 11:48:27 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=A9=B9=20Change=20regex=20pattern=20t?= =?UTF-8?q?o=20use=20[\\s\\S]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 📝 Code commentary updated to reflect change to `[\\s\\S]`. ✅ Tested on both default and Beehiiv feeds. --- .../Sources/RSCore/Shared/String+RSCore.swift | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/RSCore/Sources/RSCore/Shared/String+RSCore.swift b/RSCore/Sources/RSCore/Shared/String+RSCore.swift index 9b4dc32cc..237a268d0 100644 --- a/RSCore/Sources/RSCore/Shared/String+RSCore.swift +++ b/RSCore/Sources/RSCore/Shared/String+RSCore.swift @@ -189,37 +189,28 @@ public extension String { /// Removes an HTML tag and everything between its start and end tags. /// - /// The regex pattern `.*?` explanation: + /// The regex pattern `[\\s\\S]*?` explanation: /// - `<` matches the literal `<` character. /// - `tag` matches the literal parameter provided to the function, e.g., `style`. /// - `>` matches the literal `>` character. - /// - `.*?` - /// - `.` matches _any_ character **except** a new line + /// - `[\\s\\S]*?` + /// - `[\\s\\S]` matches _any_ character, including new lines. /// - `*` will match zero or more of the preceeding character, in this case _any_ - /// character + /// character. /// - `?` switches the matching mode to [lazy](https://javascript.info/regexp-greedy-and-lazy) /// so it will match as few as characters as possible before satisfying the rest of the pattern. /// - `<` matches the literal `<` character. /// - `/` matches the literal `/` character. - /// - `tag` matches the literal parameter provided to the function, e.g., `style` + /// - `tag` matches the literal parameter provided to the function, e.g., `style`. /// - `>` matches the literal `>` character. /// - /// /// - Parameter tag: The tag to remove. /// /// - Returns: A new copy of `self` with the tag removed. /// /// - Note: Doesn't work correctly with nested tags of the same name. private func removingTagAndContents(_ tag: String) -> String { - let pattern = "<\(tag)>.*?<\\/\(tag)>" - if let regex = try? NSRegularExpression(pattern: pattern, options: [.dotMatchesLineSeparators, .caseInsensitive]) { - let range = NSRange(location: 0, length: self.utf16.count) - let modifiedString = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: "") - return modifiedString - } else { - // If the above regex fails, fall back to the original method. - return self.replacingOccurrences(of: "<\(tag).+?", with: "", options: [.regularExpression, .caseInsensitive]) - } + return self.replacingOccurrences(of: "<\(tag)>[\\s\\S]*?", with: "", options: [.regularExpression, .caseInsensitive]) } /// Strips HTML from a string.