@@ -476,8 +476,73 @@ private static void appendProperty(final StringBuilder builder, final String ind
476
476
if (builder .length () > 0 ) {
477
477
builder .append ('\n' );
478
478
}
479
- builder .append (indent ).append ("<property name=\" " ).append (name )
480
- .append ("\" value=\" " ).append (value ).append ("\" />" );
479
+
480
+ // Check for quotes in the original, unescaped value
481
+ final boolean containsDoubleQuote = value .contains ("\" " );
482
+ final boolean containsSingleQuote = value .contains ("'" );
483
+
484
+ // Determine the appropriate quote character
485
+ final char quote ;
486
+ if (containsDoubleQuote && !containsSingleQuote ) {
487
+ // Use single quotes as delimiters
488
+ quote = '\'' ;
489
+ }
490
+ else {
491
+ // Use double quotes as delimiters in all other cases
492
+ quote = '"' ;
493
+ }
494
+
495
+ // Escape the value based on the selected quote character
496
+ final String escapedValue = escapeXmlAttributeValue (value , quote );
497
+
498
+ // Append the property to the builder
499
+ builder .append (indent )
500
+ .append ("<property name=\" " )
501
+ .append (escapeXml (name ))
502
+ .append ("\" value=" )
503
+ .append (quote )
504
+ .append (escapedValue )
505
+ .append (quote )
506
+ .append ("/>" );
507
+ }
508
+
509
+ /**
510
+ * Escapes special XML characters in the input string.
511
+ * Replaces &, <, >, ", and ' with their corresponding XML entities.
512
+ * Returns the original input if null or empty.
513
+ *
514
+ * @param input the string to escape
515
+ * @return the escaped string or the original if null/empty
516
+ */
517
+ private static String escapeXml (final String input ) {
518
+ String result = input ;
519
+ if (input != null && !input .isEmpty ()) {
520
+ result = input .replace ("\" " , """ )
521
+ .replace ("'" , "'" );
522
+ }
523
+ return result ;
524
+ }
525
+
526
+ /**
527
+ * Escapes special characters in an XML attribute value.
528
+ * Replaces &, <, > with their corresponding XML entities.
529
+ * Depending on the delimiter, either ' or " is also escaped.
530
+ *
531
+ * @param input the string to escape
532
+ * @param delimiter the delimiter used for the attribute (' or ")
533
+ * @return the escaped string or the original if null/empty
534
+ */
535
+ private static String escapeXmlAttributeValue (final String input , final char delimiter ) {
536
+ String result = input ;
537
+ if (input != null && !input .isEmpty ()) {
538
+ if (delimiter == '\'' ) {
539
+ result = result .replace ("'" , "'" );
540
+ }
541
+ else {
542
+ result = result .replace ("\" " , """ );
543
+ }
544
+ }
545
+ return result ;
481
546
}
482
547
483
548
/**
0 commit comments