Skip to content

std::net::Ipv4Addr parsing violates the "strict" form in IETF RFC 6943 Section 3.1.1. #86964

Closed
@zacknewman

Description

@zacknewman

According to the std::net::Ipv4Addr documentation, "The four octets are in decimal notation, divided by . (this is called 'dot-decimal notation'). Notably, octal numbers and hexadecimal numbers are not allowed per IETF RFC 6943"; however the parsing of the &str 127.0000.0.1 violates the "strict" form mentioned in Section 3.1.1.—this form is what prohibits octal and hexadecimal numbers—meanwhile the &str 127.0.0.001 conforms to it. IETF RFC 6943 Section 3.1.1. states:

If the af argument of inet_pton() is AF_INET, the src string shall
be in the standard IPv4 dotted-decimal form:

ddd.ddd.ddd.ddd

where "ddd" is a one to three digit decimal number between 0 and
255. The inet_pton() function does not accept other formats (such
as the octal numbers, hexadecimal numbers, and fewer than four
numbers that inet_addr() accepts).
As shown above, inet_pton() uses what we will refer to as the
"strict" form of an IPv4 address literal. Some platforms also use
the strict form with getaddrinfo() when the AI_NUMERICHOST flag is
passed to it.

I tried this code:

use std::net::Ipv4Addr;
fn main() {

    // This causes a panic despite violating the "strict" form
    // mentioned in RFC 6943 Section 3.1.1. specifically
    // the fact the second octet is represented as a 4-digit base-10
    // number.
    assert!("127.0000.0.1".parse::<Ipv4Addr>().is_err());
    // This causes a panic despite conforming to the "strict" form
    // mentioned in RFC 6943 Section 3.1.1. specifically
    // it is a string of exactly 4 octets separated by '.'
    // where each octet is represented as a one-to-three digit
    // base-10 number.
    assert!("127.0.0.001".parse::<Ipv4Addr>().is_ok())
}

I expected to see this happen: both assert!s not causing a panic since the first &str has an octet represented by more than three base-10 numbers despite the requirement per RFC 6943 stating each octet be a "one to three digit decimal number". The second &str is valid per RFC 6943 since it is a string of exactly 4 octets separated by . where each octet is a "one to three digit decimal number".

Instead, this happened: Both lines cause a panic.

Meta

rustc --version --verbose:

rustc 1.53.0 (53cb7b09b 2021-06-17)
binary: rustc
commit-hash: 53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b
commit-date: 2021-06-17
host: x86_64-apple-darwin
release: 1.53.0
LLVM version: 12.0.1

rustc --version --verbose:

rustc 1.55.0-nightly (885399992 2021-07-06)
binary: rustc
commit-hash: 885399992c4c1dde37b506b8507a7d69415646b9
commit-date: 2021-07-06
host: x86_64-apple-darwin
release: 1.55.0-nightly
LLVM version: 12.0.1
Backtrace

thread 'main' panicked at 'assertion failed: \"127.0000.0.1\".parse::<Ipv4Addr>().is_err()', src/main.rs:8:5
stack backtrace:
   0: rust_begin_unwind
             at /rustc/885399992c4c1dde37b506b8507a7d69415646b9/library/std/src/panicking.rs:515:5
   1: core::panicking::panic_fmt
             at /rustc/885399992c4c1dde37b506b8507a7d69415646b9/library/core/src/panicking.rs:92:14
   2: core::panicking::panic
             at /rustc/885399992c4c1dde37b506b8507a7d69415646b9/library/core/src/panicking.rs:50:5
   3: playground::main
             at /Users/zack/Documents/rust/playground/src/main.rs:8:5
   4: core::ops::function::FnOnce::call_once
             at /rustc/885399992c4c1dde37b506b8507a7d69415646b9/library/core/src/ops/function.rs:227:5

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions