fix: the CSV round trip keeps values that start with an apostrophe before a formula character (WR-21)
escapeCell left '=x as it was and unescapeCell then dropped its apostrophe on import. A value of apostrophes followed by a formula character now gets one more apostrophe on export, and the import drops exactly one, so unescapeCell is the inverse of escapeCell.
This commit is contained in:
@@ -38,19 +38,27 @@ func formulaStart(s string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// escapable reports whether s is a formula cell behind any number of
|
||||
// apostrophes: the cells escapeCell prefixes.
|
||||
func escapable(s string) bool {
|
||||
return formulaStart(strings.TrimLeft(s, "'"))
|
||||
}
|
||||
|
||||
// escapeCell prefixes a formula cell with an apostrophe (CSV formula
|
||||
// injection, T-32-24).
|
||||
// injection, T-32-24). A value that already starts with apostrophes before
|
||||
// a formula character gets one more, so unescapeCell is its exact inverse
|
||||
// and '=x survives a round trip (WR-21).
|
||||
func escapeCell(s string) string {
|
||||
if formulaStart(s) {
|
||||
if escapable(s) {
|
||||
return "'" + s
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// unescapeCell drops the apostrophe escapeCell added, so an exported file
|
||||
// imports unchanged.
|
||||
// unescapeCell drops the one apostrophe escapeCell added, so an exported
|
||||
// file imports unchanged.
|
||||
func unescapeCell(s string) string {
|
||||
if strings.HasPrefix(s, "'") && formulaStart(s[1:]) {
|
||||
if strings.HasPrefix(s, "'") && escapable(s[1:]) {
|
||||
return s[1:]
|
||||
}
|
||||
return s
|
||||
|
||||
Reference in New Issue
Block a user