@@ -27,6 +27,7 @@ import {
2727 sortLineSelections ,
2828 rangeFromStringDefinition ,
2929 escapeEndOfLineForCsv ,
30+ escapeDoubleQuotesForCsv ,
3031 standardizeFilename ,
3132 splitStringDefinition ,
3233} from './utils/workspace-util' ;
@@ -113,6 +114,22 @@ export class ExportFactory {
113114 ) ;
114115 }
115116
117+ /**
118+ * Properly escape newlines and quotes in CVS entries
119+ * @param entry The CVS entry to escape
120+ */
121+ private escapeCVSEntry ( entry : CsvEntry ) : CsvEntry {
122+ entry . comment = escapeEndOfLineForCsv ( escapeDoubleQuotesForCsv ( entry . comment ) ) ;
123+ entry . title = entry . title ? escapeDoubleQuotesForCsv ( entry . title ) : entry . title ;
124+ entry . filename = escapeDoubleQuotesForCsv ( entry . filename ) ;
125+ entry . lines = escapeDoubleQuotesForCsv ( entry . lines ) ;
126+ entry . sha = escapeDoubleQuotesForCsv ( entry . sha ) ;
127+ entry . additional = entry . additional ? escapeDoubleQuotesForCsv ( entry . additional ) : entry . additional ;
128+ entry . category = escapeDoubleQuotesForCsv ( entry . category ) ;
129+
130+ return entry ;
131+ }
132+
116133 private exportHandlerMap = new Map < ExportFormat , ExportMap > ( [
117134 [
118135 'html' ,
@@ -216,7 +233,7 @@ export class ExportFactory {
216233 fs . writeFileSync ( outputFile , `title,description${ EOL } ` ) ;
217234 } ,
218235 handleData : ( outputFile : string , row : CsvEntry ) : CsvEntry => {
219- row . comment = escapeEndOfLineForCsv ( row . comment ) ;
236+ row = this . escapeCVSEntry ( row ) ;
220237
221238 this . includeCodeSelection ? ( row . code = this . getCodeForFile ( row . filename , row . lines ) ) : delete row . code ;
222239 // cut the description (100 chars max) along with '...' at the end
@@ -249,7 +266,7 @@ export class ExportFactory {
249266 fs . writeFileSync ( outputFile , `title,body,labels,state,assignee${ EOL } ` ) ;
250267 } ,
251268 handleData : ( outputFile : string , row : CsvEntry ) : CsvEntry => {
252- row . comment = escapeEndOfLineForCsv ( row . comment ) ;
269+ row = this . escapeCVSEntry ( row ) ;
253270
254271 this . includeCodeSelection ? ( row . code = this . getCodeForFile ( row . filename , row . lines ) ) : delete row . code ;
255272 // cut the description (100 chars max) along with '...' at the end
@@ -288,7 +305,7 @@ export class ExportFactory {
288305 ) ;
289306 } ,
290307 handleData : ( outputFile : string , row : CsvEntry ) : CsvEntry => {
291- row . comment = escapeEndOfLineForCsv ( row . comment ) ;
308+ row = this . escapeCVSEntry ( row ) ;
292309
293310 this . includeCodeSelection ? ( row . code = this . getCodeForFile ( row . filename , row . lines ) ) : delete row . code ;
294311 // cut the description (100 chars max) along with '...' at the end
0 commit comments