Skip to content

Commit 67b9be2

Browse files
authored
Merge pull request #966 from sigstore/unknown-fields
ignoreUnknownFields when parsing json
2 parents 0057cb1 + ae16075 commit 67b9be2

File tree

9 files changed

+80
-11
lines changed

9 files changed

+80
-11
lines changed

config/forbiddenApis.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
com.google.protobuf.util.JsonFormat#parser() @ Use dev.sigstore.json.ProtoJson#parser() instead

sigstore-java/build.gradle.kts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,13 @@ jsonSchema2Pojo {
116116
}
117117
}
118118

119+
forbiddenApis {
120+
// Don't allow sigstore-java developers to directly call JsonFormat.parser(), use our wrapper instead
121+
// which allows for ignored fields.
122+
signaturesFiles = files("$rootDir/config/forbiddenApis.txt")
123+
suppressAnnotations = setOf("dev.sigstore.forbidden.SuppressForbidden")
124+
}
125+
119126
// TODO: keep until these code gen plugins explicitly declare dependencies
120127
tasks.named("sourcesJar") {
121128
dependsOn("generateJsonSchema2DataClassConfigRekor")

sigstore-java/src/main/java/dev/sigstore/bundle/BundleReader.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
package dev.sigstore.bundle;
1717

1818
import com.google.protobuf.ByteString;
19-
import com.google.protobuf.util.JsonFormat;
19+
import dev.sigstore.json.ProtoJson;
2020
import dev.sigstore.proto.ProtoMutators;
2121
import dev.sigstore.proto.common.v1.HashAlgorithm;
2222
import dev.sigstore.rekor.client.ImmutableInclusionProof;
@@ -36,7 +36,7 @@ class BundleReader {
3636
static Bundle readBundle(Reader jsonReader) throws BundleParseException {
3737
var protoBundleBuilder = dev.sigstore.proto.bundle.v1.Bundle.newBuilder();
3838
try {
39-
JsonFormat.parser().merge(jsonReader, protoBundleBuilder);
39+
ProtoJson.parser().merge(jsonReader, protoBundleBuilder);
4040
} catch (IOException ioe) {
4141
throw new BundleParseException("Could not process bundle json", ioe);
4242
}

sigstore-java/src/main/java/dev/sigstore/bundle/BundleVerifier.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@
2121
import com.google.protobuf.InvalidProtocolBufferException;
2222
import com.google.protobuf.MessageOrBuilder;
2323
import com.google.protobuf.util.JsonFormat;
24+
import dev.sigstore.json.ProtoJson;
2425
import dev.sigstore.proto.bundle.v1.Bundle;
2526
import java.util.ArrayList;
2627
import java.util.List;
2728
import java.util.Map;
2829

2930
/** Implements Sigstore Bundle verification. */
3031
public class BundleVerifier {
31-
static final JsonFormat.Parser JSON_PARSER = JsonFormat.parser();
32+
static final JsonFormat.Parser JSON_PARSER = ProtoJson.parser();
3233

3334
/**
3435
* Parses Sigstore Bundle JSON into protobuf.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* Copyright 2025 The Sigstore Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package dev.sigstore.forbidden;
17+
18+
import java.lang.annotation.ElementType;
19+
import java.lang.annotation.Retention;
20+
import java.lang.annotation.RetentionPolicy;
21+
import java.lang.annotation.Target;
22+
23+
/**
24+
* Annotation to suppress forbidden apis errors. Try to scope this as tightly as possible to the
25+
* class, method or field in question.
26+
*/
27+
@Retention(RetentionPolicy.CLASS)
28+
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
29+
public @interface SuppressForbidden {
30+
String reason();
31+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright 2025 The Sigstore Authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package dev.sigstore.json;
17+
18+
import com.google.protobuf.util.JsonFormat;
19+
import dev.sigstore.forbidden.SuppressForbidden;
20+
21+
/** Use this instead of JsonFormat to pick up default formatter options for sigstore-java. */
22+
public class ProtoJson {
23+
24+
/** Default parser to use for sigstore parsing that doesn't fail with unknown fields */
25+
@SuppressForbidden(reason = "JsonFormat#parser")
26+
public static JsonFormat.Parser parser() {
27+
return JsonFormat.parser().ignoringUnknownFields();
28+
}
29+
}

sigstore-java/src/main/java/dev/sigstore/trustroot/SigstoreSigningConfig.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616
package dev.sigstore.trustroot;
1717

18-
import com.google.protobuf.util.JsonFormat;
18+
import dev.sigstore.json.ProtoJson;
1919
import dev.sigstore.proto.trustroot.v1.SigningConfig;
2020
import java.io.IOException;
2121
import java.io.InputStream;
@@ -66,7 +66,7 @@ static SigstoreSigningConfig from(SigningConfig proto) throws SigstoreConfigurat
6666
static SigstoreSigningConfig from(InputStream json) throws SigstoreConfigurationException {
6767
var signingConfigBuilder = SigningConfig.newBuilder();
6868
try (var reader = new InputStreamReader(json, StandardCharsets.UTF_8)) {
69-
JsonFormat.parser().merge(reader, signingConfigBuilder);
69+
ProtoJson.parser().merge(reader, signingConfigBuilder);
7070
} catch (IOException ex) {
7171
throw new SigstoreConfigurationException("Could not parse signing configuration", ex);
7272
}

sigstore-java/src/main/java/dev/sigstore/trustroot/SigstoreTrustedRoot.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
package dev.sigstore.trustroot;
1717

1818
import com.google.api.client.util.Lists;
19-
import com.google.protobuf.util.JsonFormat;
19+
import dev.sigstore.json.ProtoJson;
2020
import dev.sigstore.proto.trustroot.v1.TrustedRoot;
2121
import dev.sigstore.proto.trustroot.v1.TrustedRootOrBuilder;
2222
import java.io.IOException;
@@ -47,7 +47,7 @@ public interface SigstoreTrustedRoot {
4747
static SigstoreTrustedRoot from(InputStream json) throws SigstoreConfigurationException {
4848
var trustedRootBuilder = TrustedRoot.newBuilder();
4949
try (var reader = new InputStreamReader(json, StandardCharsets.UTF_8)) {
50-
JsonFormat.parser().merge(reader, trustedRootBuilder);
50+
ProtoJson.parser().merge(reader, trustedRootBuilder);
5151
} catch (IOException ex) {
5252
throw new SigstoreConfigurationException("Could not parse trusted root", ex);
5353
}

sigstore-java/src/test/java/dev/sigstore/timestamp/client/TimestampVerifierTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import static org.junit.jupiter.api.Assertions.assertThrows;
2222

2323
import com.google.common.io.Resources;
24-
import com.google.protobuf.util.JsonFormat;
24+
import dev.sigstore.json.ProtoJson;
2525
import dev.sigstore.proto.trustroot.v1.TrustedRoot;
2626
import dev.sigstore.trustroot.SigstoreTrustedRoot;
2727
import java.io.IOException;
@@ -93,7 +93,7 @@ public static void initTrustRoot() throws Exception {
9393
Resources.getResource("dev/sigstore/trustroot/trusted_root.json"),
9494
StandardCharsets.UTF_8);
9595
var builder = TrustedRoot.newBuilder();
96-
JsonFormat.parser().merge(json, builder);
96+
ProtoJson.parser().merge(json, builder);
9797

9898
trustedRoot = SigstoreTrustedRoot.from(builder.build());
9999

@@ -102,7 +102,7 @@ public static void initTrustRoot() throws Exception {
102102
Resources.getResource("dev/sigstore/trustroot/trusted_root_with_outdated_tsa.json"),
103103
StandardCharsets.UTF_8);
104104
builder = TrustedRoot.newBuilder();
105-
JsonFormat.parser().merge(json, builder);
105+
ProtoJson.parser().merge(json, builder);
106106

107107
trustedRootWithOutdatedTsa = SigstoreTrustedRoot.from(builder.build());
108108

@@ -111,7 +111,7 @@ public static void initTrustRoot() throws Exception {
111111
Resources.getResource("dev/sigstore/trustroot/trusted_root_with_multiple_tsas.json"),
112112
StandardCharsets.UTF_8);
113113
builder = TrustedRoot.newBuilder();
114-
JsonFormat.parser().merge(json, builder);
114+
ProtoJson.parser().merge(json, builder);
115115

116116
trustedRootWithMultipleTsas = SigstoreTrustedRoot.from(builder.build());
117117
}

0 commit comments

Comments
 (0)