-
Notifications
You must be signed in to change notification settings - Fork 227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve yaml serialization quoting #4217
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -504,11 +504,27 @@ String prefixLines(String text, {String prefix = '| ', String? firstPrefix}) { | |
return lines.join('\n'); | ||
} | ||
|
||
/// The subset of strings that don't need quoting in YAML. | ||
/// | ||
/// This pattern does not strictly follow the plain scalar grammar of YAML, | ||
/// which means some strings may be unnecessarily quoted, but it's much simpler. | ||
final _unquotableYamlString = RegExp(r'^[a-zA-Z_-][a-zA-Z_0-9-]*$'); | ||
/// Does this string need quoting in yaml? | ||
/// | ||
/// This mechanism does not strictly follow the plain scalar grammar of YAML, | ||
/// which means some strings may be unnecessarily quoted. | ||
bool _needsYamlQuotes(String s) { | ||
// These must be quoted | ||
if ([ | ||
'true', 'True', 'TRUE', // | ||
'false', 'False', 'FALSE', | ||
'null', 'Null', 'NULL', | ||
].contains(s)) return true; | ||
// Numbers must be quoted | ||
if (RegExp(r'^[-+]?[0-9]*\.?[0-9]*(e[0-9]+)?$').hasMatch(s)) return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a potentially dangerous RegExp because of the Consider changing to |
||
// Hex numbers must be quoted | ||
if (RegExp(r'^0x[0-9]+$').hasMatch(s)) return true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably be |
||
|
||
// Single non-number words containing a few special cases are ok. | ||
if (RegExp(r'^[\.a-zA-Z_0-9-]+$').hasMatch(s)) return false; | ||
// We are unsure, better safe than sorry | ||
return true; | ||
} | ||
|
||
/// Converts [data], which is a parsed YAML object, to a pretty-printed string, | ||
/// using indentation for maps. | ||
|
@@ -536,7 +552,7 @@ String yamlToString(Object? data) { | |
first = false; | ||
|
||
var keyString = key; | ||
if (key is! String || !_unquotableYamlString.hasMatch(key)) { | ||
if (key is! String || _needsYamlQuotes(key)) { | ||
keyString = jsonEncode(key); | ||
} | ||
|
||
|
@@ -552,7 +568,7 @@ String yamlToString(Object? data) { | |
var string = data; | ||
|
||
// Don't quote plain strings if not needed. | ||
if (data is! String || !_unquotableYamlString.hasMatch(data)) { | ||
if (data is! String || _needsYamlQuotes(data)) { | ||
string = jsonEncode(data); | ||
} | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
List can be
const
. (Small save, but save, over creating a new list on every invocation.)