From 218610ea33ef22ec1836f4fd43c3223676de5e51 Mon Sep 17 00:00:00 2001 From: Victor Nova Date: Fri, 28 Oct 2022 16:00:56 -0700 Subject: [PATCH] fixed positive PyInt converted to negative BigInteger BigInteger constructor uses the sign bit in the first byte. Since we explicitly handle the sign, the fix is to prepend a zero byte to the number, which does not change it, but ensures sign bit is zero. fixes https://github.com/pythonnet/pythonnet/issues/1990 --- CHANGELOG.md | 1 + src/embed_tests/TestPyInt.cs | 17 ++++++++++++----- src/runtime/PythonTypes/PyInt.cs | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9781f289c..71c36b412 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][]. ### Fixed - Fixed objects leaking when Python attached event handlers to them even if they were later removed +- Fixed `PyInt` conversion to `BigInteger` and `System.String` produced incorrect result for values between 128 and 255. ## [3.0.0](https://github.com/pythonnet/pythonnet/releases/tag/v3.0.0) - 2022-09-29 diff --git a/src/embed_tests/TestPyInt.cs b/src/embed_tests/TestPyInt.cs index 822fe0715..c147e074b 100644 --- a/src/embed_tests/TestPyInt.cs +++ b/src/embed_tests/TestPyInt.cs @@ -191,16 +191,23 @@ public void ToBigInteger() { 0, 1, 2, 0x10, + 0x79, + 0x80, + 0x81, + 0xFF, 0x123, + 0x8000, 0x1234, + 0x8001, + 0x4000, + 0xFF, }; simpleValues = simpleValues.Concat(simpleValues.Select(v => -v)).ToArray(); - foreach (var val in simpleValues) - { - var pyInt = new PyInt(val); - Assert.AreEqual((BigInteger)val, pyInt.ToBigInteger()); - } + var expected = simpleValues.Select(v => new BigInteger(v)).ToArray(); + var actual = simpleValues.Select(v => new PyInt(v).ToBigInteger()).ToArray(); + + CollectionAssert.AreEqual(expected, actual); } [Test] diff --git a/src/runtime/PythonTypes/PyInt.cs b/src/runtime/PythonTypes/PyInt.cs index 6b3dbf210..e71462b74 100644 --- a/src/runtime/PythonTypes/PyInt.cs +++ b/src/runtime/PythonTypes/PyInt.cs @@ -212,7 +212,7 @@ public BigInteger ToBigInteger() offset++; neg = true; } - byte[] littleEndianBytes = new byte[(hex.Length - offset + 1) / 2]; + byte[] littleEndianBytes = new byte[(hex.Length - offset + 1) / 2 + 1]; for (; offset < hex.Length; offset++) { int littleEndianHexIndex = hex.Length - 1 - offset;