Skip to content

feat: make JSON lib configurable #2088

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api-bucket-notification.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import (
"net/url"
"time"

"github.com/goccy/go-json"
"github.com/minio/minio-go/v7/internal/json"
"github.com/minio/minio-go/v7/pkg/notification"
"github.com/minio/minio-go/v7/pkg/s3utils"
)
Expand Down
2 changes: 1 addition & 1 deletion api-bucket-replication.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ package minio
import (
"bytes"
"context"
"encoding/json"
"encoding/xml"
"io"
"net/http"
"net/url"
"time"

"github.com/google/uuid"
"github.com/minio/minio-go/v7/internal/json"
"github.com/minio/minio-go/v7/pkg/replication"
"github.com/minio/minio-go/v7/pkg/s3utils"
)
Expand Down
2 changes: 1 addition & 1 deletion api-prompt-object.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"io"
"net/http"

"github.com/goccy/go-json"
"github.com/minio/minio-go/v7/internal/json"
"github.com/minio/minio-go/v7/pkg/s3utils"
)

Expand Down
2 changes: 1 addition & 1 deletion api-put-object-fan-out.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package minio

import (
"context"
"encoding/json"
"errors"
"io"
"mime/multipart"
Expand All @@ -28,6 +27,7 @@ import (
"strings"
"time"

"github.com/minio/minio-go/v7/internal/json"
"github.com/minio/minio-go/v7/pkg/encrypt"
)

Expand Down
49 changes: 49 additions & 0 deletions internal/json/json_goccy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//go:build !stdlibjson

/*
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
* Copyright 2025 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package json

import "github.com/goccy/go-json"

// This file defines the JSON functions used internally and forwards them
// to goccy/go-json. Alternatively, the standard library can be used by setting
// the build tag stdlibjson. This can be useful for testing purposes or if
// goccy/go-json causes issues.
//
// This file does not contain all definitions from goccy/go-json; if needed, more
// can be added, but keep in mind that json_stdlib.go will also need to be
// updated.

var (
// Unmarshal is a wrapper around goccy/go-json Unmarshal function.
Unmarshal = json.Unmarshal
// Marshal is a wrapper around goccy/go-json Marshal function.
Marshal = json.Marshal
// NewEncoder is a wrapper around goccy/go-json NewEncoder function.
NewEncoder = json.NewEncoder
// NewDecoder is a wrapper around goccy/go-json NewDecoder function.
NewDecoder = json.NewDecoder
)

type (
// Encoder is an alias for goccy/go-json Encoder.
Encoder = json.Encoder
// Decoder is an alias for goccy/go-json Decoder.
Decoder = json.Decoder
)
49 changes: 49 additions & 0 deletions internal/json/json_stdlib.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//go:build stdlibjson

/*
* MinIO Go Library for Amazon S3 Compatible Cloud Storage
* Copyright 2025 MinIO, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package json

import "encoding/json"

// This file defines the JSON functions used internally and forwards them
// to encoding/json. This is only enabled by setting the build tag stdlibjson,
// otherwise json_goccy.go applies.
// This can be useful for testing purposes or if goccy/go-json (which is used otherwise) causes issues.
//
// This file does not contain all definitions from encoding/json; if needed, more
// can be added, but keep in mind that json_goccy.go will also need to be
// updated.

var (
// Unmarshal is a wrapper around encoding/json Unmarshal function.
Unmarshal = json.Unmarshal
// Marshal is a wrapper around encoding/json Marshal function.
Marshal = json.Marshal
// NewEncoder is a wrapper around encoding/json NewEncoder function.
NewEncoder = json.NewEncoder
// NewDecoder is a wrapper around encoding/json NewDecoder function.
NewDecoder = json.NewDecoder
)

type (
// Encoder is an alias for encoding/json Encoder.
Encoder = json.Encoder
// Decoder is an alias for encoding/json Decoder.
Decoder = json.Decoder
)
2 changes: 1 addition & 1 deletion pkg/credentials/file_aws_credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
package credentials

import (
"encoding/json"
"errors"
"os"
"os/exec"
Expand All @@ -27,6 +26,7 @@ import (
"time"

"github.com/go-ini/ini"
"github.com/minio/minio-go/v7/internal/json"
)

// A externalProcessCredentials stores the output of a credential_process
Expand Down
2 changes: 1 addition & 1 deletion pkg/credentials/file_minio_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"path/filepath"
"runtime"

"github.com/goccy/go-json"
"github.com/minio/minio-go/v7/internal/json"
)

// A FileMinioClient retrieves credentials from the current user's home
Expand Down
2 changes: 1 addition & 1 deletion pkg/credentials/iam_aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import (
"strings"
"time"

"github.com/goccy/go-json"
"github.com/minio/minio-go/v7/internal/json"
)

// DefaultExpiryWindow - Default expiry window.
Expand Down
2 changes: 1 addition & 1 deletion pkg/encrypt/server-side.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"errors"
"net/http"

"github.com/goccy/go-json"
"github.com/minio/minio-go/v7/internal/json"
"golang.org/x/crypto/argon2"
)

Expand Down
3 changes: 2 additions & 1 deletion pkg/lifecycle/lifecycle.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@
package lifecycle

import (
"encoding/json"
"encoding/xml"
"errors"
"time"

"github.com/minio/minio-go/v7/internal/json"
)

var errMissingStorageClass = errors.New("storage-class cannot be empty")
Expand Down
3 changes: 2 additions & 1 deletion pkg/lifecycle/lifecycle_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ package lifecycle

import (
"bytes"
"encoding/json"
"encoding/xml"
"testing"
"time"

"github.com/minio/minio-go/v7/internal/json"
)

func TestLifecycleUnmarshalJSON(t *testing.T) {
Expand Down
13 changes: 12 additions & 1 deletion pkg/policy/bucket-policy-condition.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@

package policy

import "github.com/minio/minio-go/v7/pkg/set"
import (
"encoding/json"

"github.com/minio/minio-go/v7/pkg/set"
)

// ConditionKeyMap - map of policy condition key and value.
type ConditionKeyMap map[string]set.StringSet
Expand Down Expand Up @@ -92,6 +96,13 @@ func (cond ConditionMap) Remove(condKey string) {
delete(cond, condKey)
}

// MarshalJSON is a custom json marshaler. It is needed due to
// https://github.com/goccy/go-json/issues/543
// and circumvents the issue by using the stdlib json package.
func (cond ConditionMap) MarshalJSON() ([]byte, error) {
return json.Marshal(map[string]ConditionKeyMap(cond))
}

// mergeConditionMap - returns new ConditionMap which contains merged key/value of two ConditionMap.
func mergeConditionMap(condMap1, condMap2 ConditionMap) ConditionMap {
out := make(ConditionMap)
Expand Down
1 change: 1 addition & 0 deletions pkg/policy/bucket-policy-condition_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ func TestConditionKeyMapAdd(t *testing.T) {

for _, testCase := range testCases {
condKeyMap.Add(testCase.key, testCase.value)
// Must be encoded with stdlib json due to https://github.com/goccy/go-json/issues/543
if data, err := json.Marshal(condKeyMap); err != nil {
t.Fatalf("Unable to marshal ConditionKeyMap to JSON, %s", err)
} else {
Expand Down
12 changes: 11 additions & 1 deletion pkg/policy/bucket-policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
package policy

import (
"encoding/json"
stdjson "encoding/json"
"errors"
"reflect"
"strings"

"github.com/minio/minio-go/v7/internal/json"
"github.com/minio/minio-go/v7/pkg/set"
)

Expand Down Expand Up @@ -121,6 +122,15 @@ type Statement struct {
Sid string
}

// MarshalJSON is a custom json marshaler. It is needed due to
// the error reported in https://github.com/goccy/go-json/pull/545
// (which prevents goccy/go-json from omitting the empty Conditions field)
// and circumvents the issue by using the stdlib json package.
func (s Statement) MarshalJSON() ([]byte, error) {
type AliasStatement Statement
return stdjson.Marshal(AliasStatement(s))
}

// BucketAccessPolicy - minio policy collection
type BucketAccessPolicy struct {
Version string // date in YYYY-MM-DD format
Expand Down
2 changes: 1 addition & 1 deletion pkg/policy/bucket-policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
package policy

import (
"encoding/json"
"fmt"
"reflect"
"testing"

"github.com/minio/minio-go/v7/internal/json"
"github.com/minio/minio-go/v7/pkg/set"
)

Expand Down
2 changes: 1 addition & 1 deletion pkg/set/stringset.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"fmt"
"sort"

"github.com/goccy/go-json"
"github.com/minio/minio-go/v7/internal/json"
)

// StringSet - uses map as set of strings.
Expand Down
Loading