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() {