This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-csv.git

commit 42ded1cf3a29f511264c76e5e3380006957f8921
Author: Gary D. Gregory <garydgreg...@gmail.com>
AuthorDate: Sat Mar 15 10:23:17 2025 -0400

    Fix possible NullPointerException in Token.toString()
---
 src/changes/changes.xml                            |  1 +
 src/main/java/org/apache/commons/csv/Token.java    | 14 +++---
 .../java/org/apache/commons/csv/TokenTest.java     | 50 ++++++++++++++++++++++
 3 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index f801b350..ba73a04a 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -50,6 +50,7 @@
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">CSVParser.parse(Path, Charset, CSVFormat) with a null CSVFormat maps 
to CSVFormat.DEFAULT (like CSVParser.parse(Reader, CSVFormat)).</action>
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">CSVParser.parse(InputStream, Charset, CSVFormat) with a null CSVFormat 
maps to CSVFormat.DEFAULT (like CSVParser.parse(Reader, CSVFormat)).</action>
       <action type="fix" dev="ggregory" due-to="Gary 
Gregory">CSVParser.parse(*) methods with a null Charset maps to 
Charset.defaultCharset().</action>
+      <action type="fix" dev="ggregory" due-to="Gary Gregory">Fix possible 
NullPointerException in Token.toString().</action>
       <!-- ADD -->
       <action type="add" dev="ggregory" due-to="Gary Gregory">Define and use 
Maven property commons.jmh.version.</action> 
       <action type="add" dev="ggregory" due-to="Gary Gregory">Add 
CSVFormat.Builder.setMaxRows(long).</action> 
diff --git a/src/main/java/org/apache/commons/csv/Token.java 
b/src/main/java/org/apache/commons/csv/Token.java
index 9e63b944..17eb4c77 100644
--- a/src/main/java/org/apache/commons/csv/Token.java
+++ b/src/main/java/org/apache/commons/csv/Token.java
@@ -24,13 +24,13 @@ import static org.apache.commons.csv.Token.Type.INVALID;
 /**
  * Internal token representation.
  * <p>
- * It is used as a contract between the lexer and the parser.
+ * This is used as a contract between the lexer and the parser.
  * </p>
  */
 final class Token {
 
     enum Type {
-        /** Token has no valid content, i.e. is in its initialized state. */
+        /** Token has no valid content, that is, is in its initialized state. 
*/
         INVALID,
 
         /** Token with content, at the beginning or in the middle of a line. */
@@ -47,13 +47,13 @@ final class Token {
     }
 
     /** Length of the initial token (content-)buffer */
-    private static final int INITIAL_TOKEN_LENGTH = 50;
+    private static final int DEFAULT_CAPACITY = 50;
 
     /** Token type */
     Token.Type type = INVALID;
 
-    /** The content buffer. */
-    final StringBuilder content = new StringBuilder(INITIAL_TOKEN_LENGTH);
+    /** The content buffer, never null. */
+    final StringBuilder content = new StringBuilder(DEFAULT_CAPACITY);
 
     /** Token ready flag: indicates a valid token with content (ready for the 
parser). */
     boolean isReady;
@@ -68,12 +68,12 @@ final class Token {
     }
 
     /**
-     * Eases IDE debugging.
+     * Converts the token state to a string to ease debugging.
      *
      * @return a string helpful for debugging.
      */
     @Override
     public String toString() {
-        return type.name() + " [" + content.toString() + "]";
+        return type + " [" + content.toString() + "]";
     }
 }
diff --git a/src/test/java/org/apache/commons/csv/TokenTest.java 
b/src/test/java/org/apache/commons/csv/TokenTest.java
new file mode 100644
index 00000000..0f7f2f1e
--- /dev/null
+++ b/src/test/java/org/apache/commons/csv/TokenTest.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ *
+ *   https://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 org.apache.commons.csv;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.EnumSource;
+
+/**
+ * Tests {@link Token}.
+ */
+public class TokenTest {
+
+    @ParameterizedTest
+    @EnumSource(Token.Type.class)
+    public void testToString(final Token.Type type) {
+        // Should never blow up
+        final Token token = new Token();
+        final String resetName = Token.Type.INVALID.name();
+        assertTrue(token.toString().contains(resetName));
+        token.reset();
+        assertTrue(token.toString().contains(resetName));
+        token.type = null;
+        assertFalse(token.toString().isEmpty());
+        token.reset();
+        token.type = type;
+        assertTrue(token.toString().contains(type.name()));
+        token.content.setLength(1000);
+        assertTrue(token.toString().contains(type.name()));
+    }
+}

Reply via email to