Assessment reports>Initia>Low findings>Bad decimal-parsing function accepts multiple dots
Category: Coding Mistakes

Bad decimal-parsing function accepts multiple dots

Low Severity
Low Impact
Low Likelihood

Description

The decimal-parsing function shown below is incorrectly implemented. A variant of this function is used in all targets listed.

public fun from_string(num: &String): Decimal256 {
    let vec = string::bytes(num);
    let len = vector::length(vec);

    let cursor = 0;
    let dot_index = 0;
    let val: u256 = 0;
    while (cursor < len) {
        let s = *vector::borrow(vec, cursor);
        cursor = cursor + 1;                

        // find `.` position
        if (s == 46) continue;

        val = val * 10;
        assert!(s >= 48 && s <= 57, error::invalid_argument(EFAILED_TO_DESERIALIZE));

        let n = (s - 48 as u256);
        val = val + n;

        if (cursor == dot_index + 1) {
            // use `<` not `<=` to safely check "out of range"
            // (i.e. to avoid fractional part checking)
            assert!(val < MAX_INTEGER_PART, error::invalid_argument(EOUT_OF_RANGE));

            dot_index = dot_index + 1;
        };
    };

    // ignore fractional part longer than `FRACTIONAL_LENGTH`
    let val = if (dot_index == len) {
        val * pow(10, FRACTIONAL_LENGTH)
    } else {
        let fractional_length = len - dot_index - 1;
        if (fractional_length > FRACTIONAL_LENGTH) {
            val / pow(10, fractional_length - FRACTIONAL_LENGTH)
        } else {
            val * pow(10, FRACTIONAL_LENGTH - fractional_length)
        }
    };

    new(val)
}

If there is more than one dot, it will still parse the value, although it will return a corrupted result.

Impact

Since output from this function from the user should be checked anyway, we have labelled this as low impact. Any attacker trying to take advantage of this bug could instead simply enter the correct formatting of the number that would be returned by an incorrect parsing of this function.

Recommendations

Adjust the algorithm to handle inputs with multiple dots in a more intuitive manner.

Remediation

Zellic © 2024Back to top ↑