Skip to content

parse_duration accepts whitespace inside numeric literals and changes the parsed value #69

@meng-xu-cs

Description

@meng-xu-cs

Summary

parse_duration currently ignores whitespace inside the active numeric span, which means malformed inputs are silently reinterpreted as different durations instead of being rejected.

This affects both:

  • integer parts, e.g. "1 2h" is parsed as 12h
  • fractional parts, e.g. "1. 5s" is parsed as 1.5s

The parser already supports whitespace between a value and its unit (for example "20 min 17 nsec"), so this report is specifically about digits continuing after whitespace has already appeared inside a number.

Disclaimer: this does not necessarily means a bug and could be interpreted as a design feature. However, even so, it might be a good idea to have some explicit documentation to rule out the confusion.

Reproduction

use std::time::Duration;
use humantime::parse_duration;

fn main() {
    assert_eq!(parse_duration("1 2h"), Ok(Duration::from_secs(12 * 60 * 60)));
    assert_eq!(parse_duration("1 2 3s"), Ok(Duration::from_secs(123)));
    assert_eq!(parse_duration("1. 5s"), Ok(Duration::new(1, 500_000_000)));
}

Expected behavior

These inputs should return a parse error.

Once a numeric literal has started, whitespace may be tolerated before the unit, but it should not allow later digits to continue the same number.

So these should stay valid:

assert!(parse_duration("20 min 17 nsec").is_ok());
assert!(parse_duration("1.5 s").is_ok());

But these should fail:

assert!(parse_duration("1 2h").is_err());
assert!(parse_duration("1 2 3s").is_err());
assert!(parse_duration("1. 5s").is_err());

Actual behavior

Whitespace is treated as ignorable while the parser is still accumulating the current integer/fractional span, so later digits are merged into the same number:

  • "1 2h"12h
  • "1 2 3s"123s
  • "1. 5s"1.5s

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions