Skip to content

Commit 218610e

Browse files
committed
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 #1990
1 parent 02b6c2f commit 218610e

File tree

3 files changed

+14
-6
lines changed

3 files changed

+14
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
1414
### Fixed
1515

1616
- Fixed objects leaking when Python attached event handlers to them even if they were later removed
17+
- Fixed `PyInt` conversion to `BigInteger` and `System.String` produced incorrect result for values between 128 and 255.
1718

1819

1920
## [3.0.0](https://github.com/pythonnet/pythonnet/releases/tag/v3.0.0) - 2022-09-29

src/embed_tests/TestPyInt.cs

+12-5
Original file line numberDiff line numberDiff line change
@@ -191,16 +191,23 @@ public void ToBigInteger()
191191
{
192192
0, 1, 2,
193193
0x10,
194+
0x79,
195+
0x80,
196+
0x81,
197+
0xFF,
194198
0x123,
199+
0x8000,
195200
0x1234,
201+
0x8001,
202+
0x4000,
203+
0xFF,
196204
};
197205
simpleValues = simpleValues.Concat(simpleValues.Select(v => -v)).ToArray();
198206

199-
foreach (var val in simpleValues)
200-
{
201-
var pyInt = new PyInt(val);
202-
Assert.AreEqual((BigInteger)val, pyInt.ToBigInteger());
203-
}
207+
var expected = simpleValues.Select(v => new BigInteger(v)).ToArray();
208+
var actual = simpleValues.Select(v => new PyInt(v).ToBigInteger()).ToArray();
209+
210+
CollectionAssert.AreEqual(expected, actual);
204211
}
205212

206213
[Test]

src/runtime/PythonTypes/PyInt.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ public BigInteger ToBigInteger()
212212
offset++;
213213
neg = true;
214214
}
215-
byte[] littleEndianBytes = new byte[(hex.Length - offset + 1) / 2];
215+
byte[] littleEndianBytes = new byte[(hex.Length - offset + 1) / 2 + 1];
216216
for (; offset < hex.Length; offset++)
217217
{
218218
int littleEndianHexIndex = hex.Length - 1 - offset;

0 commit comments

Comments
 (0)