Skip to content

[SUGGESTION] Cppfront could prevent implicit truncation and conversion when functions return numeric types #437

Description

@bluetarpmedia

Suggestion
Cppfront could report errors when detecting implicit numeric truncation and/or conversion in function return statements.
These would be compile-time only checks for:

  • numeric literals having invalid values for the function's return type
  • expressions having a type incompatible with the function's return type

Examples:

t1: () -> uchar = {
    return -1;  // Invalid literal (signed/unsigned)
}

t2: () -> char = {
    return 300;  // Invalid literal (out-of-range for type)
}

t3: () -> i32 = {
    return 4'000'000'000;  // Invalid literal (out-of-range for type)
}

t4: () -> i32 = {
    return 1.0;  // Invalid literal (not an integer literal)
}

t5_helper: () -> i32 = {
    return std::numeric_limits<int>::min();
}

t5: () -> ushort = {
    return t5_helper();  // t5_helper returns i32, incompatible with ushort
}

Will your feature suggestion eliminate X% of security vulnerabilities of a given kind in current C++ code?
Yes, see:

(There are various CVEs listed for these weaknesses but I couldn't find any with source code.)

Here's a Cpp2 snippet based on examples from the above CWE links:

enum {
    kError_InvalidDimensions = -1
};

get_image_data_size: (width: u32, height: u32) -> u32 = {
    if (width > 1024 && height > 1024)
    {
        return width * height;
    }
    else if (width > 512)
    {
        return width;
    }
    else if (width > 256)
    {
        return width / 2;
    }
    else
    {
        return kError_InvalidDimensions;  // Oops, programmer bug
    }
}

copy_image_data: (dst: *char, src: *const char, width: u32, height: u32) = {
    std::memcpy(dst, src, get_image_data_size(width, height));
}

Will your feature suggestion automate or eliminate X% of current C++ guidance literature?
Yes, it automates the guidance to compile at high warning levels. See:

Using the above Cpp2 example, there are no warnings from the 3 major compilers about return kError_InvalidDimensions with default options. To produce a warning:

  • MSVC 19: requires /W4
  • Clang 15: requires -Wconversion

I couldn't get a warning in GCC 12.2 even with -Wall -Wextra -Wpedantic -Wconversion -Wsign-conversion
https://godbolt.org/z/M9bb46j4T

Describe alternatives you've considered.
One alternative is to provide runtime checks which would validate the actual value rather than just the type itself.

get_internal_count: () -> i32 = {
    return 5;
}

// This is fine; the value 5 returned as an i32 can fit inside uchar without any truncation or signed conversion.
get_usage_count: () -> uchar = {
    return cpp2_runtime_check<uchar>(get_internal_count());
}

However, this could possibly introduce a significant runtime overhead for functions called in hot loops, and would probably require an opt-in/out preference, whereas the suggestion above is for compile-time only checks.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions