Skip to content

Commit

Permalink
A few tweaks for fixing issue #412: Convert::NativeToInt64 with SUPPO…
Browse files Browse the repository at this point in the history
…RT_ANY_BASE_CONVERSION delivers incorrect results (#855)

Signed-off-by: Matthias Jentsch <info@matthias-jentsch.de>
  • Loading branch information
MatthiasJentsch authored Sep 15, 2018
1 parent 566b0bb commit 92f8b1b
Showing 1 changed file with 21 additions and 1 deletion.
22 changes: 21 additions & 1 deletion src/CLR/CorLib/corlib_native_System_Convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,29 @@ HRESULT Library_corlib_native_System_Convert::NativeToInt64___STATIC__I8__STRING
long long minValue = stack.Arg2().NumericByRef().s8;
long long maxValue = stack.Arg3().NumericByRef().s8;

// normally we check if the result is in the given range
bool check = true;

// Int64? => use also strtoull the result will be casted to Int64
if (isSigned && maxValue == 0x7FFFFFFFFFFFFFFF) isSigned = false;

// UInt64? => use also strtoull the result will be casted to Int64 and bypass the range check
if (minValue == 0 && maxValue == 0)
{
isSigned = false;
check = false;
}

// convert via strtoll / strtoull
result = isSigned ? strtoll(str, nullptr, radix) : (long long) strtoull(str, nullptr, radix);

stack.SetResult_I8 ((result > maxValue || result < minValue) ? zero : result);
// the signed values for SByte, Int16 and Int32 are always positive for base 2, 8 or 16 conversions
// because the 64-bit function strtoll is used; need the post process the value
// if the result is greater max and smaller (max + 1) * 2 this value should be subtracted
if (isSigned && result > maxValue && result < (maxValue + 1) * 2) result -= (maxValue + 1) * 2;

// for UInt64 the check will be bypassed
stack.SetResult_I8 ((check && (result > maxValue || result < minValue)) ? zero : result);

#else
// support for conversion from base 10 and 16 (partial)
Expand Down

0 comments on commit 92f8b1b

Please sign in to comment.