diff --git a/geojson/feature.go b/geojson/feature.go index ba2d712..dea91f4 100644 --- a/geojson/feature.go +++ b/geojson/feature.go @@ -78,6 +78,10 @@ func (f *Feature) UnmarshalJSON(data []byte) error { return fmt.Errorf("geojson: not a feature: type=%s", jf.Type) } + if jf.Geometry == nil || jf.Geometry.Coordinates == nil { + return ErrInvalidGeometry + } + *f = Feature{ ID: jf.ID, Type: jf.Type, diff --git a/geojson/feature_test.go b/geojson/feature_test.go index 295b3bc..549837e 100644 --- a/geojson/feature_test.go +++ b/geojson/feature_test.go @@ -146,6 +146,26 @@ func TestUnmarshalFeature(t *testing.T) { } } +func TestUnmarshalFeature_missingGeometry(t *testing.T) { + t.Run("empty geometry", func(t *testing.T) { + rawJSON := `{ "type": "Feature", "geometry": {} }` + + _, err := UnmarshalFeature([]byte(rawJSON)) + if err != ErrInvalidGeometry { + t.Fatalf("incorrect unmarshal error: %v", err) + } + }) + + t.Run("missing geometry", func(t *testing.T) { + rawJSON := `{ "type": "Feature" }` + + _, err := UnmarshalFeature([]byte(rawJSON)) + if err != ErrInvalidGeometry { + t.Fatalf("incorrect unmarshal error: %v", err) + } + }) +} + func TestUnmarshalFeature_BBox(t *testing.T) { rawJSON := ` { "type": "Feature", diff --git a/geojson/geometry.go b/geojson/geometry.go index 06712dd..aa7e6f0 100644 --- a/geojson/geometry.go +++ b/geojson/geometry.go @@ -7,6 +7,9 @@ import ( "github.com/paulmach/orb" ) +// ErrInvalidGeometry will be returned if a the json of the geometry is invalid. +var ErrInvalidGeometry = errors.New("geojson: invalid geometry") + // A Geometry matches the structure of a GeoJSON Geometry. type Geometry struct { Type string `json:"type"` @@ -105,6 +108,7 @@ func (g *Geometry) UnmarshalJSON(data []byte) error { if err != nil { return err } + switch jg.Type { case "Point": p := orb.Point{} @@ -133,10 +137,10 @@ func (g *Geometry) UnmarshalJSON(data []byte) error { case "GeometryCollection": g.Geometries = jg.Geometries default: - return errors.New("geojson: invalid geometry") + return ErrInvalidGeometry } - return err + return nil } // A Point is a helper type that will marshal to/from a GeoJSON Point geometry.