Skip to content

Commit cc87783

Browse files
author
Alex Huszagh
committed
Fixed an integer overflow bug and a read-1-past-the-array.
1 parent 759a74d commit cc87783

File tree

22 files changed

+223
-25
lines changed

22 files changed

+223
-25
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license = "MIT/Apache-2.0"
99
name = "lexical"
1010
readme = "README.md"
1111
repository = "https://github.com/Alexhuszagh/rust-lexical"
12-
version = "1.8.0"
12+
version = "1.8.1"
1313
exclude = [
1414
"data/*",
1515
"benches/*",

lexical-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ license = "MIT/Apache-2.0"
99
name = "lexical-core"
1010
readme = "README.md"
1111
repository = "https://github.com/Alexhuszagh/rust-lexical/tree/master/lexical-core"
12-
version = "0.1.1"
12+
version = "0.1.2"
1313

1414
[badges]
1515
travis-ci = { repository = "Alexhuszagh/rust-lexical" }

lexical-core/README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Low-level, FFI-compatible, lexical conversion routines for use in a `no_std` con
1414
- [Float to String](#float-to-string)
1515
- [String to Float](#string-to-float)
1616
- [Arbitrary-Precision Arithmetic](#arbitrary-precision-arithmetic)
17-
- [Comparison to Algorithm M and dtoa](#comparison-to-algorithm-m-and-dtoa)
17+
- [Algorithm Background and Comparison](#algorithm-background-and-comparison)
1818

1919
# Features
2020

@@ -37,13 +37,15 @@ Float parsing is difficult to do correctly, and major bugs have been found in im
3737

3838
Although Lexical may contain bugs leading to rounding error, it is tested against a comprehensive suite of random-data and near-halfway representations, and should be fast and correct for the vast majority of use-cases.
3939

40+
Finally, due to the heavy use of unsafe code, Lexical-core is fuzzed using cargo-fuzz, to avoid memory errors.
41+
4042
# Caveats
4143

4244
Lexical uses unsafe code in the back-end for performance, and therefore may introduce memory-safety issues. Although the code is tested with wide variety of inputs to minimize the risk of memory-safety bugs, and then unittests are run are under Valgrind, no guarantees are made and you should use it at your own risk.
4345

4446
Finally, for non-decimal (base 10) floats, lexical's float-to-string implementation is lossy, resulting in rounding for a small subset of inputs (up to 0.1% of the total value).
4547

46-
# Details
48+
# Implementation Details
4749

4850
## Float to String
4951

@@ -68,9 +70,9 @@ To use Algorithm M, use the feature `algorithm_m` when compiling lexical.
6870

6971
## Arbitrary-Precision Arithmetic
7072

71-
Lexical uses arbitrary-precision arithmetic to exactly represent strings between two floating-point representations with more than 36 digits, with various optimizations for multiplication and division relative to Rust's current implementation. The arbitrary-precision arithmetic logic is not independent on memory allocation: the default slow-path algorithm only uses the stack, while Algorithm M uses the heap.
73+
Lexical uses arbitrary-precision arithmetic to exactly represent strings between two floating-point representations with more than 36 digits, with various optimizations for multiplication and division relative to Rust's current implementation. The arbitrary-precision arithmetic logic is not independent on memory allocation: the default slow-path algorithm only uses the stack, and Algorithm M only uses the heap when the `radix` feature is enabled.
7274

73-
## Comparison to Algorithm M
75+
## Algorithm Background and Comparison
7476

7577
For close-to-halfway representations of a decimal string `s`, where `s` is close between two representations, `b` and the next float `b+u`, arbitrary-precision arithmetic is used to determine the correct representation. This means `s` is close to `b+h`, where `h` is the halfway point between `b` and `b+u`.
7678

lexical-core/fuzz/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
target
3+
corpus
4+
artifacts

lexical-core/fuzz/Cargo.toml

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
2+
[package]
3+
name = "lexical-core-fuzz"
4+
version = "0.0.1"
5+
authors = ["Alex Huszagh <ahuszagh@gmail.com>"]
6+
publish = false
7+
8+
[package.metadata]
9+
cargo-fuzz = true
10+
11+
[dependencies.lexical-core]
12+
path = ".."
13+
14+
[dependencies.libfuzzer-sys]
15+
git = "https://github.com/rust-fuzz/libfuzzer-sys.git"
16+
17+
# Prevent this from interfering with workspaces
18+
[workspace]
19+
members = ["."]
20+
21+
[[bin]]
22+
name = "atof32"
23+
path = "fuzz_targets/atof32.rs"
24+
25+
[[bin]]
26+
name = "atof64"
27+
path = "fuzz_targets/atof64.rs"
28+
29+
[[bin]]
30+
name = "atoi8"
31+
path = "fuzz_targets/atoi8.rs"
32+
33+
[[bin]]
34+
name = "atoi16"
35+
path = "fuzz_targets/atoi16.rs"
36+
37+
[[bin]]
38+
name = "atoi32"
39+
path = "fuzz_targets/atoi32.rs"
40+
41+
[[bin]]
42+
name = "atoi64"
43+
path = "fuzz_targets/atoi64.rs"
44+
45+
[[bin]]
46+
name = "atoi128"
47+
path = "fuzz_targets/atoi128.rs"
48+
49+
[[bin]]
50+
name = "atoisize"
51+
path = "fuzz_targets/atoisize.rs"
52+
53+
[[bin]]
54+
name = "atou8"
55+
path = "fuzz_targets/atou8.rs"
56+
57+
[[bin]]
58+
name = "atou16"
59+
path = "fuzz_targets/atou16.rs"
60+
61+
[[bin]]
62+
name = "atou32"
63+
path = "fuzz_targets/atou32.rs"
64+
65+
[[bin]]
66+
name = "atou64"
67+
path = "fuzz_targets/atou64.rs"
68+
69+
[[bin]]
70+
name = "atou128"
71+
path = "fuzz_targets/atou128.rs"
72+
73+
[[bin]]
74+
name = "atousize"
75+
path = "fuzz_targets/atousize.rs"
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![no_main]
2+
#[macro_use] extern crate libfuzzer_sys;
3+
extern crate lexical_core;
4+
5+
fuzz_target!(|data: &[u8]| {
6+
let _ = lexical_core::atof::try_atof32_slice(10, data);
7+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![no_main]
2+
#[macro_use] extern crate libfuzzer_sys;
3+
extern crate lexical_core;
4+
5+
fuzz_target!(|data: &[u8]| {
6+
let _ = lexical_core::atof::try_atof64_slice(10, data);
7+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![no_main]
2+
#[macro_use] extern crate libfuzzer_sys;
3+
extern crate lexical_core;
4+
5+
fuzz_target!(|data: &[u8]| {
6+
let _ = lexical_core::atoi::try_atoi128_slice(10, data);
7+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![no_main]
2+
#[macro_use] extern crate libfuzzer_sys;
3+
extern crate lexical_core;
4+
5+
fuzz_target!(|data: &[u8]| {
6+
let _ = lexical_core::atoi::try_atoi16_slice(10, data);
7+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#![no_main]
2+
#[macro_use] extern crate libfuzzer_sys;
3+
extern crate lexical_core;
4+
5+
fuzz_target!(|data: &[u8]| {
6+
let _ = lexical_core::atoi::try_atoi32_slice(10, data);
7+
});

0 commit comments

Comments
 (0)