Repository: googleapis/google-http-java-client
Pull request #1810 (2023-01-29 02:02:46)

deps: update dependency com.fasterxml.jackson.core:jackson-core to v2.14.2
[![Mend Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
| [com.fasterxml.jackson.core:jackson-core](https://togithub.com/FasterXML/jackson-core) | `2.14.1` -> `2.14.2` | [![age](https://badges.renovateapi.com/packages/maven/com.fasterxml.jackson.core:jackson-core/2.14.2/age-slim)](https://docs.renovatebot.com/merge-confidence/) | [![adoption](https://badges.renovateapi.com/packages/maven/com.fasterxml.jackson.core:jackson-core/2.14.2/adoption-slim)](https://docs.renovatebot.com/merge-confidence/) | [![passing](https://badges.renovateapi.com/packages/maven/com.fasterxml.jackson.core:jackson-core/2.14.2/compatibility-slim/2.14.1)](https://docs.renovatebot.com/merge-confidence/) | [![confidence](https://badges.renovateapi.com/packages/maven/com.fasterxml.jackson.core:jackson-core/2.14.2/confidence-slim/2.14.1)](https://docs.renovatebot.com/merge-confidence/) |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Mend Renovate](https://www.mend.io/free-developer-tools/renovate/). View repository job log [here](https://app.renovatebot.com/dashboard#github/googleapis/google-http-java-client).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNC45Ny42IiwidXBkYXRlZEluVmVyIjoiMzQuMTI1LjEifQ==-->



Patch:
diff --git a/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonFactory.java b/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonFactory.java
index f02ba0f3..6c89dd16 100644
--- a/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonFactory.java
+++ b/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonFactory.java
@@ -52,12 +52,23 @@ public class GsonFactory extends JsonFactory {
     return InstanceHolder.INSTANCE;
   }
 
+  /** Controls the behavior of leniency in reading JSON value */
+  private boolean readLeniency = false;
+
   /** Holder for the result of {@link #getDefaultInstance()}. */
   @Beta
   static class InstanceHolder {
     static final GsonFactory INSTANCE = new GsonFactory();
   }
 
+  // Keeping the default, non-arg constructor for backward compatibility. Users should use
+  // getDefaultInstance() or builder() instead.
+  public GsonFactory() {}
+
+  private GsonFactory(Builder builder) {
+    readLeniency = builder.readLeniency;
+  }
+
   @Override
   public JsonParser createJsonParser(InputStream in) {
     return createJsonParser(new InputStreamReader(in, StandardCharsets.UTF_8));
@@ -90,4 +101,36 @@ public class GsonFactory extends JsonFactory {
   public JsonGenerator createJsonGenerator(Writer writer) {
     return new GsonGenerator(this, new JsonWriter(writer));
   }
+
+  /** Returns true if it is lenient to input JSON value. */
+  boolean getReadLeniency() {
+    return readLeniency;
+  }
+
+  /** Returns the builder * */
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  /** Builder for GsonFactory. */
+  public static final class Builder {
+    // Do not directly call this constructor
+    private Builder() {}
+
+    private boolean readLeniency = false;
+
+    /**
+     * Set to {@code true} when you want to the JSON parser to be lenient to reading JSON value. By
+     * default, it is {@code false}.
+     */
+    public Builder setReadLeniency(boolean readLeniency) {
+      this.readLeniency = readLeniency;
+      return this;
+    }
+
+    /** Builds GsonFactory instance. */
+    public GsonFactory build() {
+      return new GsonFactory(this);
+    }
+  }
 }
diff --git a/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonParser.java b/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonParser.java
index dc90369c..cee6fadc 100644
--- a/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonParser.java
+++ b/google-http-client-gson/src/main/java/com/google/api/client/json/gson/GsonParser.java
@@ -43,7 +43,7 @@ class GsonParser extends JsonParser {
   GsonParser(GsonFactory factory, JsonReader reader) {
     this.factory = factory;
     this.reader = reader;
-    reader.setLenient(false);
+    reader.setLenient(factory.getReadLeniency());
   }
 
   @Override
diff --git a/pom.xml b/pom.xml
index bb41ebf0..203ea033 100644
--- a/pom.xml
+++ b/pom.xml
@@ -565,7 +565,7 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.jsr305.version>3.0.2</project.jsr305.version>
     <project.gson.version>2.10.1</project.gson.version>
-    <project.jackson-core2.version>2.14.1</project.jackson-core2.version>
+    <project.jackson-core2.version>2.14.2</project.jackson-core2.version>
     <project.protobuf-java.version>3.21.12</project.protobuf-java.version>
     <project.guava.version>30.1.1-android</project.guava.version>
     <project.xpp3.version>1.1.4c</project.xpp3.version>


Test patch:
diff --git a/google-http-client-gson/src/test/java/com/google/api/client/json/gson/GsonFactoryTest.java b/google-http-client-gson/src/test/java/com/google/api/client/json/gson/GsonFactoryTest.java
index 05ab5bf0..5d166e68 100644
--- a/google-http-client-gson/src/test/java/com/google/api/client/json/gson/GsonFactoryTest.java
+++ b/google-http-client-gson/src/test/java/com/google/api/client/json/gson/GsonFactoryTest.java
@@ -14,10 +14,16 @@
 
 package com.google.api.client.json.gson;
 
+import com.google.api.client.json.GenericJson;
 import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.JsonObjectParser;
 import com.google.api.client.json.JsonParser;
 import com.google.api.client.test.json.AbstractJsonFactoryTest;
+import com.google.gson.stream.MalformedJsonException;
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 
 /**
@@ -94,4 +100,30 @@ public class GsonFactoryTest extends AbstractJsonFactoryTest {
       assertNotNull(ex.getMessage());
     }
   }
+
+  public final void testReaderLeniency_lenient() throws IOException {
+    JsonObjectParser parser =
+        new JsonObjectParser(GsonFactory.builder().setReadLeniency(true).build());
+
+    // This prefix in JSON body is used to prevent Cross-site script inclusion (XSSI).
+    InputStream inputStream =
+        new ByteArrayInputStream((")]}'\n" + JSON_ENTRY_PRETTY).getBytes(StandardCharsets.UTF_8));
+    GenericJson json = parser.parseAndClose(inputStream, StandardCharsets.UTF_8, GenericJson.class);
+
+    assertEquals("foo", json.get("title"));
+  }
+
+  public final void testReaderLeniency_not_lenient_by_default() throws IOException {
+    JsonObjectParser parser = new JsonObjectParser(GsonFactory.getDefaultInstance());
+
+    try {
+      // This prefix in JSON body is used to prevent Cross-site script inclusion (XSSI).
+      InputStream inputStream =
+          new ByteArrayInputStream((")]}'\n" + JSON_ENTRY_PRETTY).getBytes(StandardCharsets.UTF_8));
+      parser.parseAndClose(inputStream, StandardCharsets.UTF_8, GenericJson.class);
+      fail("The read leniency should fail the JSON input with XSSI prefix.");
+    } catch (MalformedJsonException ex) {
+      assertNotNull(ex.getMessage());
+    }
+  }
 }