Skip to content

Commit 3415b0a

Browse files
committed
Merge branch 'main' into digits
2 parents c4a7dfb + 17f2cd7 commit 3415b0a

25 files changed

+717
-154
lines changed

.github/workflows/codeql-analysis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ name: "CodeQL"
1313

1414
on:
1515
push:
16-
branches: [ master ]
16+
branches: [ main ]
1717
pull_request:
1818
# The branches below must be a subset of the branches above
19-
branches: [ master ]
19+
branches: [ main ]
2020
schedule:
2121
- cron: '16 17 * * 5'
2222

.github/workflows/go.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ name: Go
44

55
on:
66
push:
7-
branches: [ "master" ]
7+
branches: [ "main" ]
88
pull_request:
9-
branches: [ "master" ]
9+
branches: [ "main" ]
1010

1111
permissions:
1212
contents: read
@@ -21,7 +21,7 @@ jobs:
2121
- name: Set up Go
2222
uses: actions/setup-go@v5
2323
with:
24-
go-version: 1.24
24+
go-version: 1.25
2525

2626
- name: Build
2727
run: go build -v ./...
@@ -32,4 +32,4 @@ jobs:
3232
- name: golangci-lint
3333
uses: golangci/golangci-lint-action@v8
3434
with:
35-
version: v2.1.6
35+
version: v2.4.0

CHANGELOG.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# CHANGELOG
22

3+
[v1.7.2](https://github.com/graph-gophers/graphql-go/releases/tag/v1.7.2) Release v1.7.2
4+
5+
* [BUGFIX] Fix checksum mismatch between direct git access and golang proxy for v1.7.1. This version contains identical functionality to v1.7.1 but with proper tag creation to ensure consistent checksums across all proxy configurations.
6+
7+
[v1.7.1](https://github.com/graph-gophers/graphql-go/releases/tag/v1.7.1) Release v1.7.1
8+
9+
* [IMPROVEMENT] `SelectedFieldNames` now returns dot-delimited nested field paths (e.g. `products`, `products.id`, `products.category`, `products.category.id`). Intermediate container object/list paths are included so resolvers can check for both a branch (`products.category`) and its leaves (`products.category.id`). `HasSelectedField` and `SortedSelectedFieldNames` operate on these paths. This aligns behavior with typical resolver projection needs and fixes missing nested selections.
10+
* [BUGFIX] Reject object, interface, and input object type definitions that declare zero fields/input values (spec compliance).
11+
* [IMPROVEMENT] Optimize overlapping field validation to avoid quadratic memory blowups on large sibling field lists.
12+
* [FEATURE] Add configurable safety valve for overlapping field comparison count with `OverlapValidationLimit(n)` schema option (0 disables the cap). When exceeded validation aborts early with rule `OverlapValidationLimitExceeded`. Disabled by default.
13+
* [TEST] Add benchmarks & randomized overlap stress test for mixed field/fragment patterns.
14+
315
[v1.7.0](https://github.com/graph-gophers/graphql-go/releases/tag/v1.7.0) Release v1.7.0
416

517
* [FEATURE] Add resolver field selection inspection helpers (`SelectedFieldNames`, `HasSelectedField`, `SortedSelectedFieldNames`). Helpers are available by default and compute results lazily only when called. An explicit opt-out (`DisableFieldSelections()` schema option) is provided for applications that want to remove even the minimal context insertion overhead when the helpers are never used.
@@ -32,7 +44,7 @@
3244

3345
* [FEATURE] Add types package #437
3446
* [FEATURE] Expose `packer.Unmarshaler` as `decode.Unmarshaler` to the public #450
35-
* [FEATURE] Add location fields to type definitions #454
47+
* [FEATURE] Add location fields to type definitions #454
3648
* [FEATURE] `errors.Errorf` preserves original error similar to `fmt.Errorf` #456
3749
* [BUGFIX] Fix duplicated __typename in response (fixes #369) #443
3850

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
- Review existing issues and provide feedback or react to them.
77

88
- With pull requests:
9-
- Open your pull request against `master`
9+
- Open your pull request against `main`
1010
- Your pull request should have no more than two commits, if not you should squash them.
1111
- It should pass all tests in the available continuous integrations systems such as TravisCI.
1212
- You should add/modify tests to cover your proposed code changes.

README.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,7 @@ func (r *helloWorldResolver) Hello(ctx context.Context) (string, error) {
9898
```
9999

100100
### Separate resolvers for different operations
101-
> **NOTE**: This feature is not in the stable release yet. In order to use it you need to run `go get github.com/graph-gophers/graphql-go@master` and in your `go.mod` file you will have something like:
102-
> ```
103-
> v1.5.1-0.20230216224648-5aa631d05992
104-
> ```
105-
> It is expected to be released in `v1.6.0` soon.
101+
This feature was released in `v1.6.0`.
106102

107103
The GraphQL specification allows for fields with the same name defined in different query types. For example, the schema below is a valid schema definition:
108104
```graphql
@@ -157,6 +153,7 @@ schema := graphql.MustParseSchema(sdl, &RootResolver{}, nil)
157153
- `PanicHandler(panicHandler errors.PanicHandler)` is used to transform panics into errors during query execution. It defaults to `errors.DefaultPanicHandler`.
158154
- `DisableIntrospection()` disables introspection queries.
159155
- `DisableFieldSelections()` disables capturing child field selections used by helper APIs (see below).
156+
- `OverlapValidationLimit(n int)` sets a hard cap on examined overlap pairs during validation; exceeding it emits `OverlapValidationLimitExceeded` error.
160157

161158
### Field Selection Inspection Helpers
162159

example/federation/integration/gateway/package-lock.json

Lines changed: 56 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

example_nullbool_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,20 @@ func (*mutnb) Toggle(args struct{ Enabled graphql.NullBool }) string {
2020
return fmt.Sprintf("enabled '%v'", *args.Enabled.Value)
2121
}
2222

23+
func (r *mutnb) Name() string {
24+
return "test"
25+
}
26+
2327
// ExampleNullBool demonstrates how to use nullable Bool type when it is necessary to differentiate between nil and not set.
2428
func ExampleNullBool() {
2529
const s = `
2630
schema {
2731
query: Query
2832
mutation: Mutation
2933
}
30-
type Query{}
34+
type Query{
35+
name: String!
36+
}
3137
type Mutation{
3238
toggle(enabled: Boolean): String!
3339
}

example_scalar_map_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ type Args struct {
3131

3232
type mutation struct{}
3333

34+
func (m *mutation) Name() string {
35+
return "test"
36+
}
37+
3438
func (*mutation) Hello(args Args) string {
3539
fmt.Println(args)
3640
return "Args accepted!"
@@ -40,7 +44,9 @@ func Example_customScalarMap() {
4044
s := `
4145
scalar Map
4246
43-
type Query {}
47+
type Query {
48+
name: String!
49+
}
4450
4551
type Mutation {
4652
hello(

example_selection_test.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,16 @@ type (
1212
userResolver struct{ u user }
1313
)
1414

15-
func (r *userResolver) ID() graphql.ID { return graphql.ID(r.u.id) }
16-
func (r *userResolver) Name() *string { return &r.u.name }
17-
func (r *userResolver) Email() *string { return &r.u.email }
18-
func (r *userResolver) Friends(ctx context.Context) []*userResolver { return nil }
15+
func (r *userResolver) ID() graphql.ID { return graphql.ID(r.u.id) }
16+
func (r *userResolver) Name() *string { return &r.u.name }
17+
func (r *userResolver) Email() *string { return &r.u.email }
18+
func (r *userResolver) Friends(ctx context.Context) []*userResolver {
19+
// Return a couple of dummy friends (data itself not important for field selection example)
20+
return []*userResolver{
21+
{u: user{id: "F1", name: "Bob"}},
22+
{u: user{id: "F2", name: "Carol"}},
23+
}
24+
}
1925

2026
type root struct{}
2127

@@ -34,8 +40,8 @@ func Example_selectedFieldNames() {
3440
type User { id: ID! name: String email: String friends: [User!]! }
3541
`
3642
schema := graphql.MustParseSchema(s, &root{})
37-
query := `query { user(id: "U1") { id name } }`
43+
query := `query { user(id: "U1") { id name friends { id name } } }`
3844
_ = schema.Exec(context.Background(), query, "", nil)
3945
// Output:
40-
// [id name]
46+
// [id name friends friends.id friends.name]
4147
}

graphql.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ type Schema struct {
8787
useFieldResolvers bool
8888
allowNullableZeroValues bool
8989
disableFieldSelections bool
90+
overlapPairLimit int
9091
}
9192

9293
// AST returns the abstract syntax tree of the GraphQL schema definition.
@@ -182,6 +183,14 @@ func MaxQueryLength(n int) SchemaOpt {
182183
}
183184
}
184185

186+
// OverlapValidationLimit caps the number of overlapping selection pairs that will be examined
187+
// during validation of a single operation (including fragments). A value of 0 disables the cap.
188+
// When the cap is exceeded validation aborts early with an error (rule: OverlapValidationLimitExceeded)
189+
// to protect against maliciously constructed queries designed to exhaust memory/CPU.
190+
func OverlapValidationLimit(n int) SchemaOpt {
191+
return func(s *Schema) { s.overlapPairLimit = n }
192+
}
193+
185194
// Tracer is used to trace queries and fields. It defaults to [noop.Tracer].
186195
func Tracer(t tracer.Tracer) SchemaOpt {
187196
return func(s *Schema) {
@@ -277,7 +286,7 @@ func (s *Schema) ValidateWithVariables(queryString string, variables map[string]
277286
return []*errors.QueryError{errors.Errorf("executable document must contain at least one operation")}
278287
}
279288

280-
return validation.Validate(s.schema, doc, variables, s.maxDepth)
289+
return validation.Validate(s.schema, doc, variables, s.maxDepth, s.overlapPairLimit)
281290
}
282291

283292
// Exec executes the given query with the schema's resolver. It panics if the schema was created
@@ -300,7 +309,7 @@ func (s *Schema) exec(ctx context.Context, queryString string, operationName str
300309
}
301310

302311
validationFinish := s.validationTracer.TraceValidation(ctx)
303-
errs := validation.Validate(s.schema, doc, variables, s.maxDepth)
312+
errs := validation.Validate(s.schema, doc, variables, s.maxDepth, s.overlapPairLimit)
304313
validationFinish(errs)
305314
if len(errs) != 0 {
306315
return &Response{Errors: errs}

0 commit comments

Comments
 (0)