Repository: getkin/kin-openapi (go)

Issue:
Additional properties false not validated
### Reproduction

```go
func TestAdditionalProperties(t *testing.T)
	schema := &openapi3.Schema{
		AdditionalProperties: openapi3.AdditionalProperties{
			Has: openapi3.BoolPtr(false),
		},
	}
	
	value := map[string]interface{}{"foo": 42}
	
	err := schema.VisitJSON(value)

	require.Error(t, err) // fails. err is nil
}
```

### Expected

I'm expecting this to return an error as `"foo"` isn't defined in `properties` and is not allowed by `additionalProperties`.

### Actual

The above test returns `nil`.


Pull request:
Fix additional properties false not validated
Resolves #746

The issue was with `Schema.IsEmpty()` assuming incorrectly that `additionalProperties=false` means empty schema while the default value for `additionalProperties` is `true`.

From the [spec](https://spec.openapis.org/oas/v3.0.3#properties):

> `additionalProperties` - Value can be boolean or object. Inline or referenced schema MUST be of a Schema Object and not a standard JSON Schema. Consistent with JSON Schema, **`additionalProperties` defaults to `true`**.


Patch:
diff --git a/openapi3/schema.go b/openapi3/schema.go
index 892f325..fbf1900 100644
--- a/openapi3/schema.go
+++ b/openapi3/schema.go
@@ -810,7 +810,7 @@ func (schema *Schema) IsEmpty() bool {
 	if ap := schema.AdditionalProperties.Schema; ap != nil && !ap.Value.IsEmpty() {
 		return false
 	}
-	if apa := schema.AdditionalProperties.Has; apa != nil && *apa {
+	if apa := schema.AdditionalProperties.Has; apa != nil && !*apa {
 		return false
 	}
 	if items := schema.Items; items != nil && !items.Value.IsEmpty() {


Test patch:
diff --git a/openapi3/issue746_test.go b/openapi3/issue746_test.go
new file mode 100644
index 0000000..390a348
--- /dev/null
+++ b/openapi3/issue746_test.go
@@ -0,0 +1,26 @@
+package openapi3
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/stretchr/testify/require"
+)
+
+func TestIssue746(t *testing.T) {
+	schema := &Schema{}
+	err := schema.UnmarshalJSON([]byte(`{"additionalProperties": false}`))
+	require.NoError(t, err)
+
+	var value interface{}
+	err = json.Unmarshal([]byte(`{"foo": "bar"}`), &value)
+	require.NoError(t, err)
+
+	err = schema.VisitJSON(value)
+	require.Error(t, err)
+
+	schemaErr := &SchemaError{}
+	require.ErrorAs(t, err, &schemaErr)
+	require.Equal(t, "properties", schemaErr.SchemaField)
+	require.Equal(t, `property "foo" is unsupported`, schemaErr.Reason)
+}