Preserve FTP password and filename whitespace
This commit is contained in:
Generated
+28
@@ -99,6 +99,7 @@ name = "memona-plugin-ftp"
|
|||||||
version = "0.1.2"
|
version = "0.1.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memona-plugin-sdk",
|
"memona-plugin-sdk",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -108,6 +109,12 @@ dependencies = [
|
|||||||
"wit-bindgen",
|
"wit-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pin-project-lite"
|
||||||
|
version = "0.2.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "prettyplease"
|
name = "prettyplease"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@@ -195,6 +202,27 @@ dependencies = [
|
|||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio"
|
||||||
|
version = "1.53.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed"
|
||||||
|
dependencies = [
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio-macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-macros"
|
||||||
|
version = "2.7.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.26"
|
version = "1.0.26"
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ crate-type = ["cdylib", "rlib"]
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
memona-plugin-sdk = { path = "sdk" }
|
memona-plugin-sdk = { path = "sdk" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tokio = { version = "1", features = ["macros", "rt"] }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
||||||
|
|||||||
+7
-2
@@ -64,7 +64,9 @@ fn names_a_conflict(text: &str) -> bool {
|
|||||||
.collect();
|
.collect();
|
||||||
words.contains(&"exists")
|
words.contains(&"exists")
|
||||||
|| words.contains(&"nonempty")
|
|| words.contains(&"nonempty")
|
||||||
|| words.windows(2).any(|pair| matches!(pair, ["not" | "non", "empty"]))
|
|| words
|
||||||
|
.windows(2)
|
||||||
|
.any(|pair| matches!(pair, ["not" | "non", "empty"]))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What the first reply to a transfer command means. A transfer answers with
|
/// What the first reply to a transfer command means. A transfer answers with
|
||||||
@@ -255,7 +257,10 @@ mod tests {
|
|||||||
));
|
));
|
||||||
// The same two conditions as other servers phrase them.
|
// The same two conditions as other servers phrase them.
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
refusal(550, "550 Cannot create a file when that file already exists."),
|
refusal(
|
||||||
|
550,
|
||||||
|
"550 Cannot create a file when that file already exists."
|
||||||
|
),
|
||||||
Err(ErrorCode::Conflict)
|
Err(ErrorCode::Conflict)
|
||||||
));
|
));
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
|
|||||||
+23
-1
@@ -31,10 +31,11 @@ struct Ftp;
|
|||||||
|
|
||||||
fn text(setting: Option<&Setting>) -> Option<String> {
|
fn text(setting: Option<&Setting>) -> Option<String> {
|
||||||
match setting {
|
match setting {
|
||||||
Some(Setting::Text(value)) | Some(Setting::Secret(value)) => {
|
Some(Setting::Text(value)) => {
|
||||||
let value = value.trim().to_owned();
|
let value = value.trim().to_owned();
|
||||||
(!value.is_empty()).then_some(value)
|
(!value.is_empty()).then_some(value)
|
||||||
}
|
}
|
||||||
|
Some(Setting::Secret(value)) => Some(value.clone()),
|
||||||
Some(Setting::Toggle(_)) | None => None,
|
Some(Setting::Toggle(_)) | None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -394,3 +395,24 @@ impl Guest for Ftp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
memona_plugin_sdk::export!(Ftp);
|
memona_plugin_sdk::export!(Ftp);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::text;
|
||||||
|
use memona_plugin_sdk::Setting;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn secret_credentials_preserve_significant_whitespace() {
|
||||||
|
for password in [" ftp fixture secret ", " ", ""] {
|
||||||
|
assert_eq!(
|
||||||
|
text(Some(&Setting::Secret(password.to_owned()))),
|
||||||
|
Some(password.to_owned())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
assert_eq!(
|
||||||
|
text(Some(&Setting::Text(" server.example ".to_owned()))),
|
||||||
|
Some("server.example".to_owned())
|
||||||
|
);
|
||||||
|
assert_eq!(text(Some(&Setting::Text(" ".to_owned()))), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+15
-1
@@ -12,7 +12,6 @@ struct Facts<'a> {
|
|||||||
|
|
||||||
fn facts(line: &str) -> Option<Facts<'_>> {
|
fn facts(line: &str) -> Option<Facts<'_>> {
|
||||||
let (facts, name) = line.split_once(' ')?;
|
let (facts, name) = line.split_once(' ')?;
|
||||||
let name = name.trim();
|
|
||||||
if name.is_empty() {
|
if name.is_empty() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@@ -106,6 +105,21 @@ mod tests {
|
|||||||
use super::{machine_entry, machine_info, page};
|
use super::{machine_entry, machine_info, page};
|
||||||
use memona_plugin_sdk::{EntryKind, ErrorCode};
|
use memona_plugin_sdk::{EntryKind, ErrorCode};
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn listing_names_preserve_significant_whitespace()
|
||||||
|
-> Result<(), ErrorCode> {
|
||||||
|
let listing = b"type=file;size=1; report.md \r\ntype=dir; spaced folder \r\ntype=file;size=2; \r\n";
|
||||||
|
let listed = page(listing, 0, 10)?;
|
||||||
|
let names: Vec<&str> = listed
|
||||||
|
.entries
|
||||||
|
.iter()
|
||||||
|
.map(|entry| entry.name.as_str())
|
||||||
|
.collect();
|
||||||
|
assert_eq!(names, [" report.md ", " spaced folder ", " "]);
|
||||||
|
assert!(listed.cursor.is_none());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reads_kind_and_size_and_skips_the_directory_itself()
|
fn reads_kind_and_size_and_skips_the_directory_itself()
|
||||||
-> Result<(), &'static str> {
|
-> Result<(), &'static str> {
|
||||||
|
|||||||
Reference in New Issue
Block a user