mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 12:07:46 +00:00
Merge pull request #5830 from sudhackar/printf-infinite-loop
printf : no infinite loop
This commit is contained in:
commit
7e3f4d8358
2 changed files with 16 additions and 1 deletions
|
@ -11,7 +11,7 @@ use std::ops::ControlFlow;
|
||||||
|
|
||||||
use clap::{crate_version, Arg, ArgAction, Command};
|
use clap::{crate_version, Arg, ArgAction, Command};
|
||||||
use uucore::error::{UResult, UUsageError};
|
use uucore::error::{UResult, UUsageError};
|
||||||
use uucore::format::{parse_spec_and_escape, FormatArgument};
|
use uucore::format::{parse_spec_and_escape, FormatArgument, FormatItem};
|
||||||
use uucore::{format_usage, help_about, help_section, help_usage};
|
use uucore::{format_usage, help_about, help_section, help_usage};
|
||||||
|
|
||||||
const VERSION: &str = "version";
|
const VERSION: &str = "version";
|
||||||
|
@ -38,14 +38,24 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut format_seen = false;
|
||||||
let mut args = values.iter().peekable();
|
let mut args = values.iter().peekable();
|
||||||
for item in parse_spec_and_escape(format_string.as_ref()) {
|
for item in parse_spec_and_escape(format_string.as_ref()) {
|
||||||
|
if let Ok(FormatItem::Spec(_)) = item {
|
||||||
|
format_seen = true;
|
||||||
|
}
|
||||||
match item?.write(stdout(), &mut args)? {
|
match item?.write(stdout(), &mut args)? {
|
||||||
ControlFlow::Continue(()) => {}
|
ControlFlow::Continue(()) => {}
|
||||||
ControlFlow::Break(()) => return Ok(()),
|
ControlFlow::Break(()) => return Ok(()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Without format specs in the string, the iter would not consume any args,
|
||||||
|
// leading to an infinite loop. Thus, we exit early.
|
||||||
|
if !format_seen {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
while args.peek().is_some() {
|
while args.peek().is_some() {
|
||||||
for item in parse_spec_and_escape(format_string.as_ref()) {
|
for item in parse_spec_and_escape(format_string.as_ref()) {
|
||||||
match item?.write(stdout(), &mut args)? {
|
match item?.write(stdout(), &mut args)? {
|
||||||
|
|
|
@ -649,3 +649,8 @@ fn partial_char() {
|
||||||
fn char_as_byte() {
|
fn char_as_byte() {
|
||||||
new_ucmd!().args(&["%c", "🙃"]).succeeds().stdout_only("ð");
|
new_ucmd!().args(&["%c", "🙃"]).succeeds().stdout_only("ð");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_infinite_loop() {
|
||||||
|
new_ucmd!().args(&["a", "b"]).succeeds().stdout_only("a");
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue