Skip to content

Commit 3c6ca8c

Browse files
sunnylqmclaude
andcommitted
Replace strtoull with manual decimal parse to drop GLIBC_2.38 requirement
std::strtoull binds __isoc23_strtoull@GLIBC_2.38 when the linux prebuild is built on Ubuntu 24.04, so the 1.3.0 prebuild fails to dlopen on any glibc < 2.38 host (Ubuntu 22.04, Debian 12, all bookworm-based node Docker images). The hand-rolled parser keeps the same accepted grammar (canonical decimal only, overflow rejected) and brings the requirement back to GLIBC_2.33, same as 1.2.2. Verified by building and running the test suite in a glibc-2.36 container and checking readelf -V output. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 4fa14e3 commit 3c6ca8c

1 file changed

Lines changed: 14 additions & 9 deletions

File tree

src/main.cc

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,7 @@
44
* Created by housisong on 2021.04.07, refactored 2026.01.20
55
*/
66
#include <napi.h>
7-
#include <cerrno>
87
#include <cmath>
9-
#include <cstdlib>
108
#include <limits>
119
#include <string>
1210
#include <utility>
@@ -41,14 +39,21 @@ namespace hdiffpatchNode
4139
}
4240

4341
inline bool parseUint64String(const std::string& value, uint64_t* out) {
42+
// 手写十进制解析而不用 strtoull:新 glibc 上 strtoull 绑定
43+
// __isoc23_strtoull@GLIBC_2.38,会把 linux prebuild 的最低 glibc
44+
// 要求抬到 2.38(Ubuntu 22.04/Debian 12 都载入失败)。
45+
// 只接受纯十进制(拒绝前导空白/'+'/'-'/十六进制),溢出返回 false。
4446
if (value.empty()) return false;
45-
// strtoull 会接受前导 '-' 并做二补回绕("-1" → UINT64_MAX),显式拒绝
46-
if (value.find('-') != std::string::npos) return false;
47-
errno = 0;
48-
char* end = nullptr;
49-
unsigned long long parsed = std::strtoull(value.c_str(), &end, 10);
50-
if (errno == ERANGE || end == value.c_str() || *end != '\0') return false;
51-
*out = static_cast<uint64_t>(parsed);
47+
uint64_t result = 0;
48+
for (const char c : value) {
49+
if (c < '0' || c > '9') return false;
50+
const uint64_t digit = static_cast<uint64_t>(c - '0');
51+
if (result > (std::numeric_limits<uint64_t>::max() - digit) / 10) {
52+
return false;
53+
}
54+
result = result * 10 + digit;
55+
}
56+
*out = result;
5257
return true;
5358
}
5459

0 commit comments

Comments
 (0)