Skip to content

Commit f58f550

Browse files
committed
replace single-quotes in string
1 parent a0b7503 commit f58f550

File tree

1 file changed

+28
-21
lines changed

1 file changed

+28
-21
lines changed

git2-hooks/src/hookspath.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use git2::Repository;
33
use crate::{error::Result, HookResult, HooksError};
44

55
use std::{
6+
ffi::OsString,
67
path::{Path, PathBuf},
78
process::Command,
89
str::FromStr,
@@ -121,35 +122,41 @@ impl HookPaths {
121122
let output = if cfg!(windows) {
122123
// execute hook in shell
123124
let command = {
124-
let mut os_str = std::ffi::OsString::new();
125+
// SEE: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_02
126+
// Enclosing characters in single-quotes ( '' ) shall preserve the literal value of each character within the single-quotes.
127+
// A single-quote cannot occur within single-quotes.
128+
const REPLACEMENT: &str = concat!(
129+
"'", // closing single-quote
130+
"\\'", // one escaped single-quote (outside of single-quotes)
131+
"'", // new single-quote
132+
);
133+
134+
let mut os_str = OsString::new();
125135
os_str.push("'");
126136
if let Some(hook) = hook.to_str() {
127-
// SEE: https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02_02
128-
// Enclosing characters in single-quotes ( '' ) shall preserve the literal value of each character within the single-quotes.
129-
// A single-quote cannot occur within single-quotes.
130-
const REPLACEMENT: &str = concat!(
131-
"'", // closing single-quote
132-
"\\'", // one escaped single-quote (outside of single-quotes)
133-
"'", // new single-quote
134-
);
135137
os_str.push(hook.replace('\'', REPLACEMENT));
136138
} else {
137139
#[cfg(windows)]
138140
{
139-
use std::os::windows::ffi::OsStrExt;
140-
if hook
141-
.as_os_str()
142-
.encode_wide()
143-
.into_iter()
144-
.find(|x| *x == (b'\'' as u16))
145-
.is_some()
146-
{
147-
// TODO: escape single quotes instead of failing
148-
return Err(HooksError::PathToString);
141+
use std::os::windows::ffi::{
142+
OsStrExt, OsStringExt,
143+
};
144+
145+
let mut new_str: Vec<u16> = vec![];
146+
147+
for ch in hook.as_os_str().encode_wide() {
148+
if ch == (b'\'' as u16) {
149+
new_str.extend(
150+
std::ffi::OsStr::new(REPLACEMENT)
151+
.encode_wide(),
152+
);
153+
} else {
154+
new_str.push(ch);
155+
}
149156
}
150-
}
151157

152-
os_str.push(hook.as_os_str());
158+
os_str.push(OsString::from_wide(&new_str));
159+
}
153160
}
154161
os_str.push("'");
155162
os_str.push(" \"$@\"");

0 commit comments

Comments
 (0)