Skip to content

Commit 361fbd0

Browse files
YohDeadfallroji
authored andcommitted
Fixes an issue with sizeof(int) in hash code calculations
1 parent 9de21a0 commit 361fbd0

3 files changed

Lines changed: 22 additions & 17 deletions

File tree

src/Npgsql/NpgsqlTypes/NpgsqlTypes.cs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public override bool Equals([CanBeNull] object obj)
6969
public static bool operator !=(NpgsqlPoint x, NpgsqlPoint y) => !(x == y);
7070

7171
public override int GetHashCode()
72-
=> X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), sizeof (int)/2);
72+
=> X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), PGUtil.BitsInInt / 2);
7373

7474
public static NpgsqlPoint Parse(string s)
7575
{
@@ -174,8 +174,10 @@ public override string ToString()
174174
=> string.Format(CultureInfo.InvariantCulture, "[{0},{1}]", Start, End);
175175

176176
public override int GetHashCode()
177-
=> Start.X.GetHashCode() ^ PGUtil.RotateShift(Start.Y.GetHashCode(), sizeof(int) / 4) ^
178-
PGUtil.RotateShift(End.X.GetHashCode(), sizeof(int) / 2) ^ PGUtil.RotateShift(End.Y.GetHashCode(), sizeof(int) * 3 / 4);
177+
=> Start.X.GetHashCode() ^
178+
PGUtil.RotateShift(Start.Y.GetHashCode(), PGUtil.BitsInInt / 4) ^
179+
PGUtil.RotateShift(End.X.GetHashCode(), PGUtil.BitsInInt / 2) ^
180+
PGUtil.RotateShift(End.Y.GetHashCode(), PGUtil.BitsInInt * 3 / 4);
179181

180182
public bool Equals(NpgsqlLSeg other) => Start == other.Start && End == other.End;
181183

@@ -239,9 +241,10 @@ public static NpgsqlBox Parse(string s)
239241
}
240242

241243
public override int GetHashCode()
242-
=> Top.GetHashCode() ^ PGUtil.RotateShift(Right.GetHashCode(), sizeof (int)/4) ^
243-
PGUtil.RotateShift(Bottom.GetHashCode(), sizeof (int)/2) ^
244-
PGUtil.RotateShift(LowerLeft.GetHashCode(), sizeof (int)*3/4);
244+
=> Top.GetHashCode() ^
245+
PGUtil.RotateShift(Right.GetHashCode(), PGUtil.BitsInInt / 4) ^
246+
PGUtil.RotateShift(Bottom.GetHashCode(), PGUtil.BitsInInt / 2) ^
247+
PGUtil.RotateShift(LowerLeft.GetHashCode(), PGUtil.BitsInInt * 3 / 4);
245248
}
246249

247250
/// <summary>
@@ -322,7 +325,7 @@ public override int GetHashCode()
322325
//The ideal amount to shift each value is one that would evenly spread it throughout
323326
//the resultant bytes. Using the current result % 32 is essentially using a random value
324327
//but one that will be the same on subsequent calls.
325-
ret ^= PGUtil.RotateShift(point.GetHashCode(), ret%sizeof (int));
328+
ret ^= PGUtil.RotateShift(point.GetHashCode(), ret % PGUtil.BitsInInt);
326329
}
327330
return Open ? ret : -ret;
328331
}
@@ -438,7 +441,7 @@ public override int GetHashCode()
438441
//The ideal amount to shift each value is one that would evenly spread it throughout
439442
//the resultant bytes. Using the current result % 32 is essentially using a random value
440443
//but one that will be the same on subsequent calls.
441-
ret ^= PGUtil.RotateShift(point.GetHashCode(), ret%sizeof (int));
444+
ret ^= PGUtil.RotateShift(point.GetHashCode(), ret % PGUtil.BitsInInt);
442445
}
443446
return ret;
444447
}

src/Npgsql/NpgsqlTypes/PostgisTypes.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public bool Equals(Coordinate2D c)
6565
// ReSharper restore CompareOfFloatsByEqualityOperator
6666

6767
public override int GetHashCode()
68-
=> X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), sizeof(int) / 2);
68+
=> X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), PGUtil.BitsInInt / 2);
6969

7070
public override bool Equals([CanBeNull] object obj)
7171
=> obj is Coordinate2D && Equals((Coordinate2D)obj);
@@ -132,7 +132,7 @@ public bool Equals([CanBeNull] PostgisPoint other)
132132

133133
public static bool operator !=(PostgisPoint x, PostgisPoint y) => !(x == y);
134134

135-
public override int GetHashCode() => X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), sizeof(int) / 2);
135+
public override int GetHashCode() => X.GetHashCode() ^ PGUtil.RotateShift(Y.GetHashCode(), PGUtil.BitsInInt / 2);
136136
}
137137

138138
/// <summary>
@@ -189,7 +189,7 @@ public override int GetHashCode()
189189
{
190190
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
191191
foreach (var t in _points)
192-
ret ^= PGUtil.RotateShift(t.GetHashCode(), ret % sizeof(int));
192+
ret ^= PGUtil.RotateShift(t.GetHashCode(), ret % PGUtil.BitsInInt);
193193
return ret;
194194
}
195195
}
@@ -256,7 +256,7 @@ public override int GetHashCode()
256256
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
257257
for (var i = 0; i < _rings.Length; i++)
258258
for (var j = 0; j < _rings[i].Length; j++)
259-
ret ^= PGUtil.RotateShift(_rings[i][j].GetHashCode(), ret % sizeof(int));
259+
ret ^= PGUtil.RotateShift(_rings[i][j].GetHashCode(), ret % PGUtil.BitsInInt);
260260
return ret;
261261
}
262262
}
@@ -318,7 +318,7 @@ public override int GetHashCode()
318318
{
319319
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
320320
for (var i = 0; i < _points.Length; i++)
321-
ret ^= PGUtil.RotateShift(_points[i].GetHashCode(), ret % sizeof(int));
321+
ret ^= PGUtil.RotateShift(_points[i].GetHashCode(), ret % PGUtil.BitsInInt);
322322
return ret;
323323
}
324324

@@ -394,7 +394,7 @@ public override int GetHashCode()
394394
{
395395
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
396396
for (var i = 0; i < _lineStrings.Length; i++)
397-
ret ^= PGUtil.RotateShift(_lineStrings[i].GetHashCode(), ret % sizeof(int));
397+
ret ^= PGUtil.RotateShift(_lineStrings[i].GetHashCode(), ret % PGUtil.BitsInInt);
398398
return ret;
399399
}
400400

@@ -453,7 +453,7 @@ public override int GetHashCode()
453453
{
454454
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
455455
for (var i = 0; i < _polygons.Length; i++)
456-
ret ^= PGUtil.RotateShift(_polygons[i].GetHashCode(), ret % sizeof(int));
456+
ret ^= PGUtil.RotateShift(_polygons[i].GetHashCode(), ret % PGUtil.BitsInInt);
457457
return ret;
458458
}
459459

@@ -516,7 +516,7 @@ public override int GetHashCode()
516516
{
517517
var ret = 266370105;//seed with something other than zero to make paths of all zeros hash differently.
518518
for (var i = 0; i < _geometries.Length; i++)
519-
ret ^= PGUtil.RotateShift(_geometries[i].GetHashCode(), ret % sizeof(int));
519+
ret ^= PGUtil.RotateShift(_geometries[i].GetHashCode(), ret % PGUtil.BitsInInt);
520520
return ret;
521521
}
522522

src/Npgsql/PGUtil.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ static class PGUtil
4848
internal static readonly UTF8Encoding UTF8Encoding = new UTF8Encoding(false, true);
4949
internal static readonly UTF8Encoding RelaxedUTF8Encoding = new UTF8Encoding(false, false);
5050

51+
internal const int BitsInInt = sizeof(int) * 8;
52+
5153
internal static void ValidateBackendMessageCode(BackendMessageCode code)
5254
{
5355
switch (code)
@@ -85,7 +87,7 @@ internal static void ValidateBackendMessageCode(BackendMessageCode code)
8587

8688
[MethodImpl(MethodImplOptions.AggressiveInlining)]
8789
internal static int RotateShift(int val, int shift)
88-
=> (val << shift) | (val >> (sizeof(int) - shift));
90+
=> (val << shift) | (val >> (BitsInInt - shift));
8991

9092
// All ReverseEndianness methods came from the System.Buffers.Binary.BinaryPrimitives class.
9193
// This takes advantage of the fact that the JIT can detect ROL32 / ROR32 patterns and output the correct intrinsic.

0 commit comments

Comments
 (0)