Cardholder name format handling belongs in openpgp-card-sequoia
This commit is contained in:
parent
d689ceb1dc
commit
92a3f76dd0
2 changed files with 22 additions and 29 deletions
|
@ -336,11 +336,16 @@ impl<'a> Card<Transaction<'a>> {
|
|||
self.state.opt.cardholder_related_data()
|
||||
}
|
||||
|
||||
// Unicode codepoints are a superset of iso-8859-1 characters
|
||||
fn latin1_to_string(s: &[u8]) -> String {
|
||||
s.iter().map(|&c| c as char).collect()
|
||||
}
|
||||
|
||||
/// Get cardholder name as a String (this also normalizes the "<" and "<<" filler chars)
|
||||
pub fn cardholder_name(&mut self) -> Result<String, Error> {
|
||||
pub fn cardholder_name(&mut self) -> Result<Option<String>, Error> {
|
||||
let crd = self.state.opt.cardholder_related_data()?;
|
||||
if let Some(name) = crd.name() {
|
||||
let name = String::from_utf8_lossy(name).to_string();
|
||||
let name = Self::latin1_to_string(name);
|
||||
|
||||
// re-format name ("last<<first")
|
||||
let name: Vec<_> = name.split("<<").collect();
|
||||
|
@ -349,9 +354,9 @@ impl<'a> Card<Transaction<'a>> {
|
|||
// replace item separators with spaces
|
||||
let name = name.replace('<', " ");
|
||||
|
||||
Ok(name)
|
||||
Ok(Some(name))
|
||||
} else {
|
||||
Ok("".to_string())
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -555,15 +560,17 @@ impl<'app, 'open> Card<Admin<'app, 'open>> {
|
|||
|
||||
impl Card<Admin<'_, '_>> {
|
||||
pub fn set_name(&mut self, name: &str) -> Result<(), Error> {
|
||||
if name.len() >= 40 {
|
||||
return Err(Error::InternalError("name too long".into()));
|
||||
}
|
||||
|
||||
// All chars must be in ASCII7
|
||||
if name.chars().any(|c| !c.is_ascii()) {
|
||||
return Err(Error::InternalError("Invalid char in name".into()));
|
||||
};
|
||||
|
||||
// FIXME: encode spaces and do ordering
|
||||
|
||||
if name.len() >= 40 {
|
||||
return Err(Error::InternalError("name too long".into()));
|
||||
}
|
||||
|
||||
self.card().set_name(name.as_bytes())
|
||||
}
|
||||
|
||||
|
|
|
@ -54,35 +54,21 @@ pub fn print_status(
|
|||
let version = ai.version().to_be_bytes();
|
||||
output.card_version(format!("{}.{}", version[0], version[1]));
|
||||
|
||||
// card / cardholder metadata
|
||||
let crd = card.cardholder_related_data()?;
|
||||
|
||||
if let Some(name) = crd.name() {
|
||||
// FIXME: decoding as utf8 is wrong (the spec defines this field as latin1 encoded)
|
||||
let name = String::from_utf8_lossy(name).to_string();
|
||||
|
||||
// // This field is silly, maybe ignore it?!
|
||||
// if let Some(sex) = crd.sex() {
|
||||
// if sex == Sex::Male {
|
||||
// print!("Mr. ");
|
||||
// } else if sex == Sex::Female {
|
||||
// print!("Mrs. ");
|
||||
// }
|
||||
// }
|
||||
|
||||
// re-format name ("last<<first")
|
||||
let name: Vec<_> = name.split("<<").collect();
|
||||
let name = name.iter().cloned().rev().collect::<Vec<_>>().join(" ");
|
||||
|
||||
// Cardholder Name
|
||||
if let Some(name) = card.cardholder_name()? {
|
||||
output.card_holder(name);
|
||||
}
|
||||
|
||||
// We ignore the Cardholder "Sex" field, because it's silly and mostly unhelpful
|
||||
|
||||
// Certificate URL
|
||||
let url = card.url()?;
|
||||
if !url.is_empty() {
|
||||
output.url(url);
|
||||
}
|
||||
|
||||
if let Some(lang) = crd.lang() {
|
||||
// Language Preference
|
||||
if let Some(lang) = card.cardholder_related_data()?.lang() {
|
||||
for lang in lang {
|
||||
output.language_preference(format!("{}", lang));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue