fix: remove leading zero-width-space from comments, ensure space after links
This commit is contained in:
parent
8cadbc1a4c
commit
162959ca45
3 changed files with 41 additions and 5 deletions
|
|
@ -250,6 +250,7 @@ fn extract_js_fn(js: &str, offset: usize, name: &str) -> Result<String, DeobfErr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Looking for variable names
|
||||||
if let Token::Ident(id) = &token {
|
if let Token::Ident(id) = &token {
|
||||||
if !period_before {
|
if !period_before {
|
||||||
let id_str = id.to_string();
|
let id_str = id.to_string();
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::convert::TryFrom;
|
use std::{borrow::Cow, convert::TryFrom};
|
||||||
|
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
use serde_with::{serde_as, DefaultOnError, DeserializeAs, VecSkipError};
|
use serde_with::{serde_as, DefaultOnError, DeserializeAs, VecSkipError};
|
||||||
|
|
@ -402,10 +402,41 @@ impl<'de> DeserializeAs<'de, TextComponents> for AttributedText {
|
||||||
.next()
|
.next()
|
||||||
.map(Verification::from)
|
.map(Verification::from)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
let mut components: Vec<TextComponent> = Vec::with_capacity(runs.len() + 1);
|
||||||
|
|
||||||
|
fn process_txt_before(components: &[TextComponent], txt_before: Cow<'_, str>) -> String {
|
||||||
|
// YouTube sometimes inserts zero-width spaces at the start of comments
|
||||||
|
let txt_before = match txt_before.strip_prefix('\u{200b}') {
|
||||||
|
Some(t) => Cow::Borrowed(t),
|
||||||
|
None => txt_before,
|
||||||
|
};
|
||||||
|
// Ensure that text after link components always begins with a space
|
||||||
|
if !txt_before
|
||||||
|
.chars()
|
||||||
|
.next()
|
||||||
|
.map(|c| c.is_whitespace())
|
||||||
|
.unwrap_or_default()
|
||||||
|
&& components
|
||||||
|
.last()
|
||||||
|
.map(|c| {
|
||||||
|
!matches!(c, TextComponent::Text { .. })
|
||||||
|
&& !c
|
||||||
|
.as_str()
|
||||||
|
.chars()
|
||||||
|
.last()
|
||||||
|
.map(|c| c.is_whitespace())
|
||||||
|
.unwrap_or_default()
|
||||||
|
})
|
||||||
|
.unwrap_or_default()
|
||||||
|
{
|
||||||
|
format!(" {txt_before}")
|
||||||
|
} else {
|
||||||
|
txt_before.into_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let mut components = Vec::with_capacity(runs.len() + 1);
|
|
||||||
for run in runs {
|
for run in runs {
|
||||||
let txt_before = take_chars(run.start_index);
|
let txt_before = process_txt_before(&components, take_chars(run.start_index).into());
|
||||||
let txt_run = take_chars(run.start_index + run.length);
|
let txt_run = take_chars(run.start_index + run.length);
|
||||||
|
|
||||||
if !txt_before.is_empty() {
|
if !txt_before.is_empty() {
|
||||||
|
|
@ -461,7 +492,7 @@ impl<'de> DeserializeAs<'de, TextComponents> for AttributedText {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let end = chars.as_str();
|
let end = process_txt_before(&components, chars.as_str().into());
|
||||||
if !end.is_empty() {
|
if !end.is_empty() {
|
||||||
components.push(TextComponent::new(end));
|
components.push(TextComponent::new(end));
|
||||||
}
|
}
|
||||||
|
|
@ -683,6 +714,10 @@ impl From<TextComponent> for String {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TextComponents {
|
impl TextComponents {
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.0.iter().all(|c| c.as_str().is_empty())
|
||||||
|
}
|
||||||
|
|
||||||
/// Return the string representation of the first text component
|
/// Return the string representation of the first text component
|
||||||
pub fn first_str(&self) -> &str {
|
pub fn first_str(&self) -> &str {
|
||||||
self.0
|
self.0
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ use rustypipe::validate;
|
||||||
#[case::desktop(ClientType::Desktop)]
|
#[case::desktop(ClientType::Desktop)]
|
||||||
#[case::tv(ClientType::Tv)]
|
#[case::tv(ClientType::Tv)]
|
||||||
#[case::mobile(ClientType::Mobile)]
|
#[case::mobile(ClientType::Mobile)]
|
||||||
// #[case::android(ClientType::Android)]
|
#[case::android(ClientType::Android)]
|
||||||
#[case::ios(ClientType::Ios)]
|
#[case::ios(ClientType::Ios)]
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn get_player_from_client(#[case] client_type: ClientType, rp: RustyPipe) {
|
async fn get_player_from_client(#[case] client_type: ClientType, rp: RustyPipe) {
|
||||||
|
|
|
||||||
Reference in a new issue