marcandrysco / Errol

Binary floating-point to decimal string conversion algorithm.
MIT License
102 stars 7 forks source link

Out of bounds write or incorrect results for large integers #12

Open ehaas opened 2 years ago

ehaas commented 2 years ago

Using the following test program, 1.0e+38 produces incorrect output, and 1.0e+37 produces undefined behavior:

#include <stdbool.h>
#include <stdio.h>
#include "errol.h"

int main(void) {
    char buf[100] = {};
    double val;
    int exp;

    val = 1.0e+38;
    exp = errol3_dtoa(val, buf);
    printf("%d %s\n", exp, buf);

    val = 1.0e+37;
    exp = errol3_dtoa(val, buf);
    printf("%d %s\n", exp, buf);
    return 0;
}

clang -v output:

Apple clang version 13.0.0 (clang-1300.0.29.30)
Target: x86_64-apple-darwin20.6.0

Compile flags: clang -fsanitize=address main.c -Ilib -Lbuild/build -lerrol

Expected output:

38 1
37 1

Actual output:

➜  Errol (master) ✗ ./a.out                                                                                                                             (master)Errol
38 :
=================================================================
==77841==ERROR: AddressSanitizer: stack-buffer-underflow on address 0x7ffeefa5a6ff at pc 0x0001001b3a91 bp 0x7ffeefa59a10 sp 0x7ffeefa59a08
READ of size 1 at 0x7ffeefa5a6ff thread T0
    #0 0x1001b3a90 in errol_int errol.c:627
    #1 0x1001b0f1e in errol3u_dtoa errol.c:393
    #2 0x1001b0b03 in errol3_dtoa errol.c:371
    #3 0x1001a6894 in main+0x154 (a.out:x86_64+0x100001894)
    #4 0x7fff2049cf3c in start+0x0 (libdyld.dylib:x86_64+0x15f3c)

Address 0x7ffeefa5a6ff is located in stack of thread T0 at offset 31 in frame
    #0 0x1001a674f in main+0xf (a.out:x86_64+0x10000174f)

  This frame has 1 object(s):
    [32, 132) 'buf' <== Memory access at offset 31 underflows this variable