Skip to content

Commit a743df1

Browse files
authored
YAML: consider starting # and ending : as quotable characters (#465)
1 parent c603bd9 commit a743df1

File tree

4 files changed

+43
-21
lines changed

4 files changed

+43
-21
lines changed

release-notes/CREDITS-2.x

+5
Original file line numberDiff line numberDiff line change
@@ -258,3 +258,8 @@ Mathieu Lavigne (@mathieu-lavigne)
258258
* Proposed #45 (and suggested implementation): (csv) Allow skipping ending line break
259259
(`CsvGenerator.Feature.WRITE_LINEFEED_AFTER_LAST_ROW`)
260260
(2.17.0)
261+
262+
Michael Edgar (@MikeEdgar)
263+
264+
* Contributed #465: (yaml) YAML: consider starting `#` and ending `:` as quotable characters
265+
(2.17.0)

release-notes/VERSION-2.x

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Active Maintainers:
1414
=== Releases ===
1515
------------------------------------------------------------------------
1616

17+
#465: (yaml) YAML: consider starting `#` and ending `:` as quotable characters
18+
(contributed by Michael E)
19+
1720
2.17.0-rc1 (26-Feb-2024)
1821

1922
#45: (csv) Allow skipping ending line break

yaml/src/main/java/com/fasterxml/jackson/dataformat/yaml/util/StringQuotingChecker.java

+31-14
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Helper class that defines API used by
99
* {@link com.fasterxml.jackson.dataformat.yaml.YAMLGenerator}
1010
* to check whether property names and String values need to be quoted or not.
11-
* Also contains default logic implementation; may be sub-classes to provide
11+
* Also contains default logic implementation; may be sub-classed to provide
1212
* alternate implementation.
1313
*
1414
* @since 2.12
@@ -58,10 +58,10 @@ public abstract class StringQuotingChecker
5858
* Helper method that sub-classes may use to see if given String value is
5959
* one of:
6060
*<ul>
61-
* <li>YAML 1.1 keyword representing
61+
* <li>YAML 1.1 keyword representing
6262
* <a href="https://yaml.org/type/bool.html">boolean</a>
6363
* </li>
64-
* <li>YAML 1.1 keyword representing
64+
* <li>YAML 1.1 keyword representing
6565
* <a href="https://yaml.org/type/null.html">null</a> value
6666
* </li>
6767
* <li>empty String (length 0)
@@ -142,20 +142,16 @@ protected boolean valueHasQuotableChar(String inputStr)
142142
return true;
143143
case '#':
144144
// [dataformats-text#201]: limit quoting with MINIMIZE_QUOTES
145-
if (i > 0) {
146-
char d = inputStr.charAt(i-1);
147-
if (' ' == d || '\t' == d) {
148-
return true;
149-
}
145+
// (but not recognized as comment unless starts line or preceded by whitespace)
146+
if (precededOnlyByBlank(inputStr, i)) {
147+
return true;
150148
}
151149
break;
152150
case ':':
153151
// [dataformats-text#201]: limit quoting with MINIMIZE_QUOTES
154-
if (i < (end-1)) {
155-
char d = inputStr.charAt(i + 1);
156-
if (' ' == d || '\t' == d) {
157-
return true;
158-
}
152+
// (but recognized as separator only if end-of-line or followed by whitespace)
153+
if (followedOnlyByBlank(inputStr, i)) {
154+
return true;
159155
}
160156
break;
161157
default:
@@ -164,6 +160,27 @@ protected boolean valueHasQuotableChar(String inputStr)
164160
return false;
165161
}
166162

163+
// @since 2.17
164+
protected boolean precededOnlyByBlank(String inputStr, int offset) {
165+
if (offset == 0) {
166+
return true;
167+
}
168+
return isBlank(inputStr.charAt(offset - 1));
169+
}
170+
171+
// @since 2.17
172+
protected boolean followedOnlyByBlank(String inputStr, int offset) {
173+
if (offset == inputStr.length() - 1) {
174+
return true;
175+
}
176+
return isBlank(inputStr.charAt(offset + 1));
177+
}
178+
179+
// @since 2.17
180+
protected boolean isBlank(char value) {
181+
return (' ' == value || '\t' == value);
182+
}
183+
167184
/**
168185
* Looks like we may get names with "funny characters" so.
169186
*
@@ -199,7 +216,7 @@ public static class Default
199216
public Default() { }
200217

201218
public static Default instance() { return INSTANCE; }
202-
219+
203220
/**
204221
* Default implementation will call
205222
* {@link #isReservedKeyword(String)} and

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/ser/GeneratorWithMinimizeTest.java

+4-7
Original file line numberDiff line numberDiff line change
@@ -119,25 +119,22 @@ public void testMinimizeQuotesWithStringsContainingSpecialChars() throws Excepti
119119
"key: f:off", yaml);
120120

121121

122-
/* scenarios with single quoted scalars */
122+
/* scenarios with double quoted scalars */
123123

124124
content = Collections.singletonMap("key", "::");
125125
yaml = MINIM_MAPPER.writeValueAsString(content).trim();
126126
assertEquals("---\n" +
127-
"key: '::'", yaml);
127+
"key: \"::\"", yaml);
128128

129129
content = Collections.singletonMap("key", "#");
130130
yaml = MINIM_MAPPER.writeValueAsString(content).trim();
131131
assertEquals("---\n" +
132-
"key: '#'", yaml);
132+
"key: \"#\"", yaml);
133133

134134
content = Collections.singletonMap("key", "#a");
135135
yaml = MINIM_MAPPER.writeValueAsString(content).trim();
136136
assertEquals("---\n" +
137-
"key: '#a'", yaml);
138-
139-
140-
/* scenarios with double quoted scalars */
137+
"key: \"#a\"", yaml);
141138

142139
content = Collections.singletonMap("key", "a[b");
143140
yaml = MINIM_MAPPER.writeValueAsString(content).trim();

0 commit comments

Comments
 (0)