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

SvenO3 pushed a commit to branch 
4564-ensure-correct-escaping-and-quoting-of-string-values-in-csv-export
in repository https://gitbox.apache.org/repos/asf/streampipes.git


The following commit(s) were added to 
refs/heads/4564-ensure-correct-escaping-and-quoting-of-string-values-in-csv-export
 by this push:
     new c6beb8a795 Escape special characters of dimension properties
c6beb8a795 is described below

commit c6beb8a79593bf11f884a7efce53e02c3db3e580
Author: Sven Oehler <[email protected]>
AuthorDate: Tue Jun 23 11:06:17 2026 +0200

    Escape special characters of dimension properties
---
 .../dataexplorer/influx/PropertyHandler.java       |  8 +++-
 .../influx/TimeSeriesStorageInfluxTest.java        | 45 ++++++++++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git 
a/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/PropertyHandler.java
 
b/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/PropertyHandler.java
index 388f9cedee..d64a106797 100644
--- 
a/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/PropertyHandler.java
+++ 
b/streampipes-data-explorer-influx/src/main/java/org/apache/streampipes/dataexplorer/influx/PropertyHandler.java
@@ -100,7 +100,13 @@ public class PropertyHandler {
       PrimitiveField primitiveField,
       String sanitizedRuntimeName
   ) {
-    point.tag(sanitizedRuntimeName, primitiveField.getAsString());
+    point.tag(sanitizedRuntimeName, 
escapeSpecialCharacters(primitiveField.getAsString()));
+  }
+
+  private String escapeSpecialCharacters(String value) {
+    return value
+        .replace("\r", "\\r")
+        .replace("\n", "\\n");
   }
 
   /**
diff --git 
a/streampipes-data-explorer-influx/src/test/java/org/apache/streampipes/dataexplorer/influx/TimeSeriesStorageInfluxTest.java
 
b/streampipes-data-explorer-influx/src/test/java/org/apache/streampipes/dataexplorer/influx/TimeSeriesStorageInfluxTest.java
index 9874f081c8..1b42595781 100644
--- 
a/streampipes-data-explorer-influx/src/test/java/org/apache/streampipes/dataexplorer/influx/TimeSeriesStorageInfluxTest.java
+++ 
b/streampipes-data-explorer-influx/src/test/java/org/apache/streampipes/dataexplorer/influx/TimeSeriesStorageInfluxTest.java
@@ -52,7 +52,9 @@ import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 public class TimeSeriesStorageInfluxTest {
 
@@ -188,6 +190,20 @@ public class TimeSeriesStorageInfluxTest {
     assertEquals(expected, actualPoint);
   }
 
+  @Test
+  public void onEventWithStringSpecialCharacters() {
+    var actualPoint = testEventWithOneField(
+        XSD.STRING,
+        "abc=;,\nquoted \"value\"\r\n"
+    );
+
+    var lineProtocol = actualPoint.lineProtocol(TimeUnit.MILLISECONDS);
+
+    assertFalse(lineProtocol.contains("\n"));
+    assertFalse(lineProtocol.contains("\r"));
+    assertTrue(lineProtocol.contains("testId=\"abc=;,\\\\nquoted 
\\\"value\\\"\\\\r\\\\n\""));
+  }
+
   @Test
   public void onEventReservedKeyWord() {
     // name is a reserved keyword
@@ -249,6 +265,35 @@ public class TimeSeriesStorageInfluxTest {
     assertEquals(expected, actualPoint);
   }
 
+  @Test
+  public void onEventWithTagSpecialCharacters() {
+    var eventSchema = getEventSchemaBuilderWithTimestamp()
+        .withEventProperty(
+            EventPropertyPrimitiveTestBuilder
+                .create()
+                .withRuntimeName(FIELD_NAME)
+                .withRuntimeType(XSD.STRING)
+                .build())
+        .withEventProperty(
+            EventPropertyPrimitiveTestBuilder
+                .create()
+                .withRuntimeName("id")
+                .withRuntimeType(XSD.STRING)
+                .withPropertyScope(PropertyScope.DIMENSION_PROPERTY)
+                .build())
+        .build();
+
+    var event = getEvent(eventSchema, Map.of(FIELD_NAME, "value", "id", 
"line\nbreak"));
+
+    var influxStore = getInfluxStore(eventSchema);
+
+    var actualPoint = executeOnEvent(influxStore, event);
+    var lineProtocol = actualPoint.lineProtocol(TimeUnit.MILLISECONDS);
+
+    assertFalse(lineProtocol.contains("\n"));
+    assertTrue(lineProtocol.contains(",id=line\\nbreak "));
+  }
+
 
   @Test
   public void onEventWithNestedProperty() {

Reply via email to