Skip to content

Commit f1ca359

Browse files
authored
Merge pull request RustPython#4421 from yt2b/implement_string_format_validation
Implement string format validation
2 parents 2f94c07 + e60a264 commit f1ca359

File tree

3 files changed

+17
-8
lines changed

3 files changed

+17
-8
lines changed

common/src/format.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,6 @@ impl FormatSpec {
522522
sign_str,
523523
FormatAlign::Right,
524524
)
525-
.map_err(|msg| msg.to_owned())
526525
}
527526

528527
#[inline]
@@ -605,10 +604,10 @@ impl FormatSpec {
605604
&sign_prefix,
606605
FormatAlign::Right,
607606
)
608-
.map_err(|msg| msg.to_owned())
609607
}
610608

611-
pub fn format_string(&self, s: &BorrowedStr) -> Result<String, &'static str> {
609+
pub fn format_string(&self, s: &BorrowedStr) -> Result<String, String> {
610+
self.validate_format(FormatType::String)?;
612611
match self.format_type {
613612
Some(FormatType::String) | None => self
614613
.format_sign_and_align(s, "", FormatAlign::Left)
@@ -618,7 +617,13 @@ impl FormatSpec {
618617
}
619618
value
620619
}),
621-
_ => Err("Unknown format code for object of type 'str'"),
620+
_ => {
621+
let ch = char::from(self.format_type.as_ref().unwrap());
622+
Err(format!(
623+
"Unknown format code '{}' for object of type 'str'",
624+
ch
625+
))
626+
}
622627
}
623628
}
624629

@@ -627,7 +632,7 @@ impl FormatSpec {
627632
magnitude_str: &BorrowedStr,
628633
sign_str: &str,
629634
default_align: FormatAlign,
630-
) -> Result<String, &'static str> {
635+
) -> Result<String, String> {
631636
let align = self.align.unwrap_or(default_align);
632637

633638
let num_chars = magnitude_str.char_len();

extra_tests/snippets/builtin_format.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,5 @@ def test_zero_padding():
7272
assert_raises(ValueError, "{:_n}".format, 1, _msg="ValueError: Cannot specify '_' with 'n'.")
7373
assert_raises(ValueError, "{:,o}".format, 1.0, _msg="ValueError: Cannot specify ',' with 'o'.")
7474
assert_raises(ValueError, "{:_n}".format, 1.0, _msg="ValueError: Cannot specify '_' with 'n'.")
75+
assert_raises(ValueError, "{:,}".format, "abc", _msg="ValueError: Cannot specify ',' with 's'.")
76+
assert_raises(ValueError, "{:,x}".format, "abc", _msg="ValueError: Cannot specify ',' with 'x'.")

vm/src/builtins/str.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,9 +730,11 @@ impl PyStr {
730730

731731
#[pymethod(name = "__format__")]
732732
fn format_str(&self, spec: PyStrRef, vm: &VirtualMachine) -> PyResult<String> {
733-
FormatSpec::parse(spec.as_str())
734-
.and_then(|format_spec| format_spec.format_string(self.borrow()))
735-
.map_err(|err| vm.new_value_error(err.to_string()))
733+
let format_spec =
734+
FormatSpec::parse(spec.as_str()).map_err(|err| vm.new_value_error(err.to_string()))?;
735+
format_spec
736+
.format_string(self.borrow())
737+
.map_err(|msg| vm.new_value_error(msg))
736738
}
737739

738740
/// Return a titlecased version of the string where words start with an

0 commit comments

Comments
 (0)