fix(go): validate string enum exclusions - #25089
AndreyVMarkelov wants to merge 7 commits into
Conversation
There was a problem hiding this comment.
All reported issues were addressed across 4 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
21e3c5e to
74d4a3f
Compare
74d4a3f to
5a21506
Compare
There was a problem hiding this comment.
All reported issues were addressed across 17 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 5 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 3 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
2bbd9d8 to
10b5284
Compare
There was a problem hiding this comment.
All reported issues were addressed across 21 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
3 issues found across 22 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java">
<violation number="1" location="modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java:271">
P2: The guard treats any installed Go binary as suitable, but generated `go.mod` requires Go 1.23; an older local toolchain can fail this test instead of skipping. Check the reported version against the module directive before invoking `go test`.</violation>
<violation number="2" location="modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java:278">
P3: This copied test file is not registered for deletion, so it prevents the temporary output directory and generated files from being removed on JVM exit. Register the copied path with `deleteOnExit()`.</violation>
</file>
<file name="modules/openapi-generator/src/main/resources/go/model_simple.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/go/model_simple.mustache:510">
P2: For a required `Foo` with a default, `{"foo":""}` reaches this branch and leaves both `foo` and the defaulted `Foo` in `allProperties`; unmarshalling the marshaled map can let the alias overwrite the default. Remove or normalize the matched alias before adding the canonical default.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| "validateStringEnumValues"); | ||
|
|
||
| try { | ||
| Process goVersion = new ProcessBuilder("go", "version").start(); |
There was a problem hiding this comment.
P2: The guard treats any installed Go binary as suitable, but generated go.mod requires Go 1.23; an older local toolchain can fail this test instead of skipping. Check the reported version against the module directive before invoking go test.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java, line 271:
<comment>The guard treats any installed Go binary as suitable, but generated `go.mod` requires Go 1.23; an older local toolchain can fail this test instead of skipping. Check the reported version against the module directive before invoking `go test`.</comment>
<file context>
@@ -256,13 +264,23 @@ public void testStringNotEnumValidation() throws IOException {
+ "validateStringEnumValues");
+
+ try {
+ Process goVersion = new ProcessBuilder("go", "version").start();
+ if (goVersion.waitFor() != 0) {
+ return;
</file context>
| for _, requiredProperty := range(requiredProperties) { | ||
| {{#useDefaultValuesForRequiredVars}} | ||
| {{#vendorExtensions.x-go-enum-required-case-fold}} | ||
| if value, exists := lookupRequiredProperty(requiredProperty); !exists || value == "" { |
There was a problem hiding this comment.
P2: For a required Foo with a default, {"foo":""} reaches this branch and leaves both foo and the defaulted Foo in allProperties; unmarshalling the marshaled map can let the alias overwrite the default. Remove or normalize the matched alias before adding the canonical default.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/main/resources/go/model_simple.mustache, line 510:
<comment>For a required `Foo` with a default, `{"foo":""}` reaches this branch and leaves both `foo` and the defaulted `Foo` in `allProperties`; unmarshalling the marshaled map can let the alias overwrite the default. Remove or normalize the matched alias before adding the canonical default.</comment>
<file context>
@@ -491,18 +491,46 @@ func (o *{{{classname}}}) UnmarshalJSON(data []byte) (err error) {
for _, requiredProperty := range(requiredProperties) {
{{#useDefaultValuesForRequiredVars}}
+{{#vendorExtensions.x-go-enum-required-case-fold}}
+ if value, exists := lookupRequiredProperty(requiredProperty); !exists || value == "" {
+{{/vendorExtensions.x-go-enum-required-case-fold}}
+{{^vendorExtensions.x-go-enum-required-case-fold}}
</file context>
| Files.copy(Paths.get("src/test/resources/3_1/go/oneof-not-enum_test.go"), | ||
| Paths.get(output.getAbsolutePath(), "oneof-not-enum_test.go")); |
There was a problem hiding this comment.
P3: This copied test file is not registered for deletion, so it prevents the temporary output directory and generated files from being removed on JVM exit. Register the copied path with deleteOnExit().
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At modules/openapi-generator/src/test/java/org/openapitools/codegen/go/GoClientCodegenTest.java, line 278:
<comment>This copied test file is not registered for deletion, so it prevents the temporary output directory and generated files from being removed on JVM exit. Register the copied path with `deleteOnExit()`.</comment>
<file context>
@@ -256,13 +264,23 @@ public void testStringNotEnumValidation() throws IOException {
+ } catch (IOException ignored) {
+ return;
+ }
+ Files.copy(Paths.get("src/test/resources/3_1/go/oneof-not-enum_test.go"),
+ Paths.get(output.getAbsolutePath(), "oneof-not-enum_test.go"));
+ Process goTest = new ProcessBuilder("go", "test", "-mod=mod", "-run", "^TestStringEnumScope$", ".")
</file context>
| Files.copy(Paths.get("src/test/resources/3_1/go/oneof-not-enum_test.go"), | |
| Paths.get(output.getAbsolutePath(), "oneof-not-enum_test.go")); | |
| Files.copy(Paths.get("src/test/resources/3_1/go/oneof-not-enum_test.go"), | |
| Paths.get(output.getAbsolutePath(), "oneof-not-enum_test.go")).toFile().deleteOnExit(); |
Description
Fixes #25090
Fix Go client generation for string properties constrained by
enumandnot: { enum: [...] }.Previously, generated models could accept values excluded by
not: enumduring JSON unmarshaling. This could makeoneOfvariants overlap when they were intended to be mutually exclusive.This change adds validation during generated model unmarshaling so:
nullsemantics;not: enumdoes not incorrectly force a string type;encoding/jsoncase-insensitive field matching.Existing
UnmarshalJSONpaths for required andadditionalPropertiesmodels are preserved.Related reports: #25065 (Java), #25069 (Python).
Tests
Added focused Go generator coverage for:
not: enumUnmarshalJSONgenerationGenerated Go code compiles and passes runtime validation with
go test ./....