diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-23 01:24:49 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-23 01:24:49 +0000 |
| commit | 0111978da7b1643d92fb70461cb44ab9723896c7 (patch) | |
| tree | cef7da32e3c41a4e99bb4d1e1a11eab2c341c509 /pseudocode-lib | |
| parent | a0dba2acdeb6e2e9af8e53a4d886fba79c7a3afe (diff) | |
fix(stdlib): reject NaN, infinity and hexadecimal text in IS_NUM, STR_TO_NUM and INPUT
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'pseudocode-lib')
| -rw-r--r-- | pseudocode-lib/README.md | 4 | ||||
| -rw-r--r-- | pseudocode-lib/string.cc | 4 |
2 files changed, 6 insertions, 2 deletions
diff --git a/pseudocode-lib/README.md b/pseudocode-lib/README.md index dbdebf3..a12620a 100644 --- a/pseudocode-lib/README.md +++ b/pseudocode-lib/README.md @@ -35,7 +35,7 @@ The library provides `&`, six case-sensitive content comparisons, and these ordi - `ASC(CHAR)` and `ASC(STRING)` return the unsigned character or first-byte code; an empty string returns zero. - `CHR(Code)` returns a CHAR containing the low eight bits. `LENGTH(CHR(0))` is 1. - `NUM_TO_STR(INTEGER)` and `NUM_TO_STR(REAL)` convert INTEGER to decimal text and REAL to the shortest round-trip text (Python `repr` style, identical to OUTPUT: `2.0`, `0.1`, `1e-07`, `inf`). -- `STR_TO_NUM(S)` accepts STRING or CHAR and returns REAL through the same `parseNumber` helper as IS_NUM (`strtod`, full consumption). Invalid text and trailing junk throw `STR_TO_NUM: '<text>' is not a number`; overflow throws `... is out of the REAL range`; underflow is accepted. -- `IS_NUM(S)` agrees with STR_TO_NUM: full consumption by `strtod` and no overflow, without throwing. Leading whitespace is accepted; trailing whitespace, trailing junk, empty input, embedded NUL bytes, and overflowing values (`1e999`) are rejected. +- `STR_TO_NUM(S)` accepts STRING or CHAR and returns REAL through the same `parseNumber` helper as IS_NUM (`strtod`, full consumption, decimal text only: nan, inf/infinity and hexadecimal are rejected). Invalid text and trailing junk throw `STR_TO_NUM: '<text>' is not a number`; overflow throws `... is out of the REAL range`; underflow is accepted. +- `IS_NUM(S)` agrees with STR_TO_NUM: full consumption by `strtod` and no overflow, without throwing. Leading whitespace is accepted; nan, inf/infinity, hexadecimal, trailing whitespace, trailing junk, empty input, embedded NUL bytes, and overflowing values (`1e999`) are rejected. Library C++ exceptions print the user call line and can be caught with TRY/CATCH. Library functions follow the guide where specified; LEFT, STRING case conversion, byte-code and numeric-conversion functions remain compatibility extensions. diff --git a/pseudocode-lib/string.cc b/pseudocode-lib/string.cc index 4395304..a20bebe 100644 --- a/pseudocode-lib/string.cc +++ b/pseudocode-lib/string.cc @@ -49,6 +49,10 @@ enum class NumberStatus { Ok, Invalid, OutOfRange }; // Shared by IS_NUM and STR_TO_NUM so that they always agree. NumberStatus parseNumber(const std::string &Source, double &Result) { if (Source.empty()) return NumberStatus::Invalid; + // Only decimal text: reject nan, inf/infinity and hexadecimal forms that strtod accepts. + if (Source.find_first_not_of("0123456789.eE+-", Source.find_first_not_of(" \t\n\v\f\r")) != + std::string::npos) + return NumberStatus::Invalid; char *End = nullptr; errno = 0; double Number = std::strtod(Source.c_str(), &End); |
