Skip to content

Commit

Permalink
Fix NRE with default NpgsqlPolygon and NpgsqlPath (#5860)
Browse files Browse the repository at this point in the history
Fixes #5854

(cherry picked from commit e433ce1)
  • Loading branch information
vonzshik committed Oct 12, 2024
1 parent db29ff3 commit c4a23cc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 34 deletions.
73 changes: 39 additions & 34 deletions src/Npgsql/NpgsqlTypes/NpgsqlTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,10 @@ void NormalizeBox()
/// </summary>
public struct NpgsqlPath : IList<NpgsqlPoint>, IEquatable<NpgsqlPath>
{
readonly List<NpgsqlPoint> _points;
List<NpgsqlPoint> _points;

List<NpgsqlPoint> Points => _points ??= new();

public bool Open { get; set; }

public NpgsqlPath()
Expand Down Expand Up @@ -231,23 +234,23 @@ public NpgsqlPath(int capacity) : this(capacity, false) {}

public NpgsqlPoint this[int index]
{
get => _points[index];
set => _points[index] = value;
get => Points[index];
set => Points[index] = value;
}

public int Capacity => _points.Capacity;
public int Count => _points.Count;
public int Capacity => Points.Capacity;
public int Count => _points?.Count ?? 0;
public bool IsReadOnly => false;

public int IndexOf(NpgsqlPoint item) => _points.IndexOf(item);
public void Insert(int index, NpgsqlPoint item) => _points.Insert(index, item);
public void RemoveAt(int index) => _points.RemoveAt(index);
public void Add(NpgsqlPoint item) => _points.Add(item);
public void Clear() => _points.Clear();
public bool Contains(NpgsqlPoint item) => _points.Contains(item);
public void CopyTo(NpgsqlPoint[] array, int arrayIndex) => _points.CopyTo(array, arrayIndex);
public bool Remove(NpgsqlPoint item) => _points.Remove(item);
public IEnumerator<NpgsqlPoint> GetEnumerator() => _points.GetEnumerator();
public int IndexOf(NpgsqlPoint item) => Points.IndexOf(item);
public void Insert(int index, NpgsqlPoint item) => Points.Insert(index, item);
public void RemoveAt(int index) => Points.RemoveAt(index);
public void Add(NpgsqlPoint item) => Points.Add(item);
public void Clear() => Points.Clear();
public bool Contains(NpgsqlPoint item) => Points.Contains(item);
public void CopyTo(NpgsqlPoint[] array, int arrayIndex) => Points.CopyTo(array, arrayIndex);
public bool Remove(NpgsqlPoint item) => Points.Remove(item);
public IEnumerator<NpgsqlPoint> GetEnumerator() => Points.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public bool Equals(NpgsqlPath other)
Expand Down Expand Up @@ -287,12 +290,12 @@ public override string ToString()
var sb = new StringBuilder();
sb.Append(Open ? '[' : '(');
int i;
for (i = 0; i < _points.Count; i++)
for (i = 0; i < Count; i++)
{
var p = _points[i];
sb.AppendFormat(CultureInfo.InvariantCulture, "({0},{1})", p.X, p.Y);
if (i < _points.Count - 1)
sb.Append(",");
sb.Append(',');
}
sb.Append(Open ? ']' : ')');
return sb.ToString();
Expand All @@ -302,9 +305,11 @@ public override string ToString()
/// <summary>
/// Represents a PostgreSQL Polygon type.
/// </summary>
public readonly struct NpgsqlPolygon : IList<NpgsqlPoint>, IEquatable<NpgsqlPolygon>
public struct NpgsqlPolygon : IList<NpgsqlPoint>, IEquatable<NpgsqlPolygon>
{
readonly List<NpgsqlPoint> _points;
List<NpgsqlPoint> _points;

List<NpgsqlPoint> Points => _points ??= new();

public NpgsqlPolygon()
=> _points = new();
Expand All @@ -319,23 +324,23 @@ public NpgsqlPolygon(int capacity)

public NpgsqlPoint this[int index]
{
get => _points[index];
set => _points[index] = value;
get => Points[index];
set => Points[index] = value;
}

public int Capacity => _points.Capacity;
public int Count => _points.Count;
public int Capacity => Points.Capacity;
public int Count => _points?.Count ?? 0;
public bool IsReadOnly => false;

public int IndexOf(NpgsqlPoint item) => _points.IndexOf(item);
public void Insert(int index, NpgsqlPoint item) => _points.Insert(index, item);
public void RemoveAt(int index) => _points.RemoveAt(index);
public void Add(NpgsqlPoint item) => _points.Add(item);
public void Clear() => _points.Clear();
public bool Contains(NpgsqlPoint item) => _points.Contains(item);
public void CopyTo(NpgsqlPoint[] array, int arrayIndex) => _points.CopyTo(array, arrayIndex);
public bool Remove(NpgsqlPoint item) => _points.Remove(item);
public IEnumerator<NpgsqlPoint> GetEnumerator() => _points.GetEnumerator();
public int IndexOf(NpgsqlPoint item) => Points.IndexOf(item);
public void Insert(int index, NpgsqlPoint item) => Points.Insert(index, item);
public void RemoveAt(int index) => Points.RemoveAt(index);
public void Add(NpgsqlPoint item) => Points.Add(item);
public void Clear() => Points.Clear();
public bool Contains(NpgsqlPoint item) => Points.Contains(item);
public void CopyTo(NpgsqlPoint[] array, int arrayIndex) => Points.CopyTo(array, arrayIndex);
public bool Remove(NpgsqlPoint item) => Points.Remove(item);
public IEnumerator<NpgsqlPoint> GetEnumerator() => Points.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public bool Equals(NpgsqlPolygon other)
Expand Down Expand Up @@ -374,7 +379,7 @@ public override string ToString()
var sb = new StringBuilder();
sb.Append('(');
int i;
for (i = 0; i < _points.Count; i++)
for (i = 0; i < Count; i++)
{
var p = _points[i];
sb.AppendFormat(CultureInfo.InvariantCulture, "({0},{1})", p.X, p.Y);
Expand Down Expand Up @@ -478,8 +483,8 @@ public NpgsqlInet(string addr)
}

public override string ToString()
=> (Address.AddressFamily == AddressFamily.InterNetwork && Netmask == 32) ||
(Address.AddressFamily == AddressFamily.InterNetworkV6 && Netmask == 128)
=> (Address?.AddressFamily == AddressFamily.InterNetwork && Netmask == 32) ||
(Address?.AddressFamily == AddressFamily.InterNetworkV6 && Netmask == 128)
? Address.ToString()
: $"{Address}/{Netmask}";

Expand Down
14 changes: 14 additions & 0 deletions test/Npgsql.Tests/TypesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,20 @@ public void NpgsqlPath_empty()
public void NpgsqlPolygon_empty()
=> Assert.That(new NpgsqlPolygon { new(1, 2) }, Is.EqualTo(new NpgsqlPolygon(new NpgsqlPoint(1, 2))));

[Test]
public void NpgsqlPath_default()
{
NpgsqlPath defaultPath = default;
Assert.IsFalse(defaultPath.Equals(new NpgsqlPath { new(1, 2) }));
}

[Test]
public void NpgsqlPolygon_default()
{
NpgsqlPolygon defaultPolygon = default;
Assert.IsFalse(defaultPolygon.Equals(new NpgsqlPolygon { new(1, 2) }));
}

[Test]
public void Bug1011018()
{
Expand Down

0 comments on commit c4a23cc

Please sign in to comment.