From 655c48961d0ca4b7ca968b3b1fba64cd7c0401eb Mon Sep 17 00:00:00 2001 From: digi-scrypt Date: Fri, 5 Jun 2026 20:36:46 +0530 Subject: [PATCH] reject new line characters in obj writer object and group names --- .../io/euclidean/threed/obj/ObjWriter.java | 17 +++++++ .../euclidean/threed/obj/ObjWriterTest.java | 46 +++++++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/commons-geometry-io-euclidean/src/main/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriter.java b/commons-geometry-io-euclidean/src/main/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriter.java index 0f00abf88..b46f86b7c 100644 --- a/commons-geometry-io-euclidean/src/main/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriter.java +++ b/commons-geometry-io-euclidean/src/main/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriter.java @@ -86,9 +86,11 @@ public void writeComment(final String comment) { * does not affect the geometry, although it may affect how the file content * is read by other programs. * @param objectName the name to write + * @throws IllegalArgumentException if {@code objectName} contains new line characters * @throws java.io.UncheckedIOException if an I/O error occurs */ public void writeObjectName(final String objectName) { + checkName("Object", objectName); writeKeywordLine(ObjConstants.OBJECT_KEYWORD, objectName); } @@ -96,9 +98,11 @@ public void writeObjectName(final String objectName) { * does not affect the geometry, although it may affect how the file content * is read by other programs. * @param groupName the name to write + * @throws IllegalArgumentException if {@code groupName} contains new line characters * @throws java.io.UncheckedIOException if an I/O error occurs */ public void writeGroupName(final String groupName) { + checkName("Group", groupName); writeKeywordLine(ObjConstants.GROUP_KEYWORD, groupName); } @@ -339,6 +343,19 @@ private void writeKeywordLine(final String keyword, final String content) { writeNewLine(); } + /** Throw an exception if the given name contains new line characters. Names are written on a + * single line, so an embedded new line would let the trailing content be interpreted as + * additional OBJ statements. + * @param type type of name being checked; used in the error message + * @param name name to check; may be null + * @throws IllegalArgumentException if {@code name} contains a '\r' or '\n' character + */ + private static void checkName(final String type, final String name) { + if (name != null && (name.indexOf('\r') > -1 || name.indexOf('\n') > -1)) { + throw new IllegalArgumentException(type + " name cannot contain new line characters"); + } + } + /** Class used to produce OBJ mesh content from sequences of facets. As facets are added to the buffer * their vertices and normals are converted to OBJ vertex and normal definition strings. Vertices and normals * that produce equal definition strings are shared among all of the facets in the buffer. This process diff --git a/commons-geometry-io-euclidean/src/test/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriterTest.java b/commons-geometry-io-euclidean/src/test/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriterTest.java index 5a7845d07..3db8418d3 100644 --- a/commons-geometry-io-euclidean/src/test/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriterTest.java +++ b/commons-geometry-io-euclidean/src/test/java/org/apache/commons/geometry/io/euclidean/threed/obj/ObjWriterTest.java @@ -153,6 +153,52 @@ void testWriteGroupName() { Assertions.assertEquals("g test-group\n", writer.getBuffer().toString()); } + @Test + void testWriteObjectName_containsNewLine() { + // arrange + final StringWriter writer = new StringWriter(); + + // act/assert + try (ObjWriter objWriter = new ObjWriter(writer)) { + final String err = "Object name cannot contain new line characters"; + + GeometryTestUtils.assertThrowsWithMessage( + () -> objWriter.writeObjectName("a\nv 0 0 0"), + IllegalArgumentException.class, err); + GeometryTestUtils.assertThrowsWithMessage( + () -> objWriter.writeObjectName("a\r\nv 0 0 0"), + IllegalArgumentException.class, err); + GeometryTestUtils.assertThrowsWithMessage( + () -> objWriter.writeObjectName("a\rv 0 0 0"), + IllegalArgumentException.class, err); + } + + Assertions.assertEquals("", writer.getBuffer().toString()); + } + + @Test + void testWriteGroupName_containsNewLine() { + // arrange + final StringWriter writer = new StringWriter(); + + // act/assert + try (ObjWriter objWriter = new ObjWriter(writer)) { + final String err = "Group name cannot contain new line characters"; + + GeometryTestUtils.assertThrowsWithMessage( + () -> objWriter.writeGroupName("a\nv 0 0 0"), + IllegalArgumentException.class, err); + GeometryTestUtils.assertThrowsWithMessage( + () -> objWriter.writeGroupName("a\r\nv 0 0 0"), + IllegalArgumentException.class, err); + GeometryTestUtils.assertThrowsWithMessage( + () -> objWriter.writeGroupName("a\rv 0 0 0"), + IllegalArgumentException.class, err); + } + + Assertions.assertEquals("", writer.getBuffer().toString()); + } + @Test void testWriteVertex() { // arrange