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 882556287e Add csv quoting
882556287e is described below

commit 882556287ed43d19821c723623d5f4027360c4e2
Author: Sven Oehler <[email protected]>
AuthorDate: Tue Jun 23 09:34:34 2026 +0200

    Add csv quoting
---
 .../export/ConfiguredCsvOutputWriter.java          |  4 +++-
 .../dataexplorer/export/item/CsvItemGenerator.java | 25 +++++++++++++++++++++-
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git 
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ConfiguredCsvOutputWriter.java
 
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ConfiguredCsvOutputWriter.java
index cbc7eaba95..fd0012d475 100644
--- 
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ConfiguredCsvOutputWriter.java
+++ 
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/ConfiguredCsvOutputWriter.java
@@ -78,7 +78,9 @@ public class ConfiguredCsvOutputWriter extends 
ConfiguredOutputWriter {
 
   private String makeHeaderLine(List<String> columns) {
     StringJoiner joiner = new StringJoiner(this.delimiter);
-    columns.forEach(c -> joiner.add(getHeaderName(schema, c, 
headerColumnNameStrategy)));
+    columns.forEach(c -> joiner.add(
+        itemGenerator.encodeCsvValue(getHeaderName(schema, c, 
headerColumnNameStrategy))
+    ));
     return joiner + LINE_SEPARATOR;
   }
 }
diff --git 
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/item/CsvItemGenerator.java
 
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/item/CsvItemGenerator.java
index 824c05f97c..0ec0c5004d 100644
--- 
a/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/item/CsvItemGenerator.java
+++ 
b/streampipes-data-explorer-export/src/main/java/org/apache/streampipes/dataexplorer/export/item/CsvItemGenerator.java
@@ -23,17 +23,40 @@ import 
org.apache.streampipes.dataexplorer.export.ExportUtils;
 
 public class CsvItemGenerator extends ItemGenerator {
 
+  private static final String QUOTE = "\"";
+  private static final String ESCAPED_QUOTE = "\"\"";
+  private static final String CARRIAGE_RETURN = "\r";
+  private static final String LINE_FEED = "\n";
+
+  private final String delimiter;
+
   public CsvItemGenerator(String delimiter) {
     super(delimiter);
+    this.delimiter = delimiter;
   }
 
   @Override
   protected String makeItemString(String key, Object value) {
-    return value != null ? ExportUtils.formatValue(value) : "";
+    return value != null ? encodeCsvValue(ExportUtils.formatValue(value)) : "";
   }
 
   @Override
   protected String finalizeItem(String item) {
     return item;
   }
+
+  public String encodeCsvValue(String value) {
+    if (requiresQuoting(value)) {
+      return QUOTE + value.replace(QUOTE, ESCAPED_QUOTE) + QUOTE;
+    } else {
+      return value;
+    }
+  }
+
+  private boolean requiresQuoting(String value) {
+    return value.contains(delimiter)
+        || value.contains(QUOTE)
+        || value.contains(CARRIAGE_RETURN)
+        || value.contains(LINE_FEED);
+  }
 }

Reply via email to