From d4867041b37f4ed0554f21b17949da20ce857a89 Mon Sep 17 00:00:00 2001 From: xuri Date: Thu, 18 Apr 2024 11:57:02 +0800 Subject: [PATCH] This closes #1879, compatible with the escaped quote symbol in none formula data validation rules - Update dependencies module to fix vulnerabilities - Update unit tests --- adjust.go | 4 ++-- adjust_test.go | 20 ++++++++++++++++++++ datavalidation.go | 7 +++++-- go.mod | 6 +++--- go.sum | 12 ++++++------ 5 files changed, 36 insertions(+), 13 deletions(-) diff --git a/adjust.go b/adjust.go index 7c8ec9ee21..583e2b979f 100644 --- a/adjust.go +++ b/adjust.go @@ -989,14 +989,14 @@ func (f *File) adjustDataValidations(ws *xlsxWorksheet, sheet string, dir adjust } worksheet.DataValidations.DataValidation[i].Sqref = ref } - if worksheet.DataValidations.DataValidation[i].Formula1 != nil { + if worksheet.DataValidations.DataValidation[i].Formula1.isFormula() { formula := formulaUnescaper.Replace(worksheet.DataValidations.DataValidation[i].Formula1.Content) if formula, err = f.adjustFormulaRef(sheet, sheetN, formula, false, dir, num, offset); err != nil { return err } worksheet.DataValidations.DataValidation[i].Formula1 = &xlsxInnerXML{Content: formulaEscaper.Replace(formula)} } - if worksheet.DataValidations.DataValidation[i].Formula2 != nil { + if worksheet.DataValidations.DataValidation[i].Formula2.isFormula() { formula := formulaUnescaper.Replace(worksheet.DataValidations.DataValidation[i].Formula2.Content) if formula, err = f.adjustFormulaRef(sheet, sheetN, formula, false, dir, num, offset); err != nil { return err diff --git a/adjust_test.go b/adjust_test.go index eb5b47391c..cde12fb287 100644 --- a/adjust_test.go +++ b/adjust_test.go @@ -4,6 +4,7 @@ import ( "encoding/xml" "fmt" "path/filepath" + "strings" "testing" _ "image/jpeg" @@ -1099,6 +1100,25 @@ func TestAdjustDataValidations(t *testing.T) { f.Sheet.Delete("xl/worksheets/sheet1.xml") f.Pkg.Store("xl/worksheets/sheet1.xml", MacintoshCyrillicCharset) assert.EqualError(t, f.adjustDataValidations(nil, "Sheet1", columns, 0, 0, 1), "XML syntax error on line 1: invalid UTF-8") + + t.Run("for_escaped_data_validation_rules_formula", func(t *testing.T) { + f := NewFile() + _, err := f.NewSheet("Sheet2") + assert.NoError(t, err) + dv := NewDataValidation(true) + dv.Sqref = "A1" + assert.NoError(t, dv.SetDropList([]string{"option1", strings.Repeat("\"", 4)})) + ws, ok := f.Sheet.Load("xl/worksheets/sheet1.xml") + assert.True(t, ok) + assert.NoError(t, f.AddDataValidation("Sheet1", dv)) + // The double quote symbol in none formula data validation rules will be escaped in the Kingsoft WPS Office + formula := strings.ReplaceAll(fmt.Sprintf("\"option1, %s", strings.Repeat("\"", 9)), "\"", """) + ws.(*xlsxWorksheet).DataValidations.DataValidation[0].Formula1.Content = formula + f.RemoveCol("Sheet2", "A") + dvs, err := f.GetDataValidations("Sheet1") + assert.NoError(t, err) + assert.Equal(t, formula, dvs[0].Formula1) + }) } func TestAdjustDrawings(t *testing.T) { diff --git a/datavalidation.go b/datavalidation.go index 3a8cdcf9fe..f42c1db903 100644 --- a/datavalidation.go +++ b/datavalidation.go @@ -76,13 +76,11 @@ var ( `&`, `&`, `<`, `<`, `>`, `>`, - `"`, """, ) formulaUnescaper = strings.NewReplacer( `&`, `&`, `<`, `<`, `>`, `>`, - """, `"`, ) // dataValidationTypeMap defined supported data validation types. dataValidationTypeMap = map[DataValidationType]string{ @@ -444,6 +442,11 @@ func squashSqref(cells [][]int) []string { return append(refs, ref) } +// isFormulaDataValidation returns whether the data validation rule is a formula. +func (dv *xlsxInnerXML) isFormula() bool { + return dv != nil && !(strings.HasPrefix(dv.Content, """) && strings.HasSuffix(dv.Content, """)) +} + // unescapeDataValidationFormula returns unescaped data validation formula. func unescapeDataValidationFormula(val string) string { if strings.HasPrefix(val, "\"") { // Text detection diff --git a/go.mod b/go.mod index 8c12fa1eb6..d9879927dd 100644 --- a/go.mod +++ b/go.mod @@ -6,11 +6,11 @@ require ( github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 github.com/richardlehane/mscfb v1.0.4 github.com/stretchr/testify v1.8.4 - github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 + github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 - golang.org/x/crypto v0.21.0 + golang.org/x/crypto v0.22.0 golang.org/x/image v0.14.0 - golang.org/x/net v0.22.0 + golang.org/x/net v0.24.0 golang.org/x/text v0.14.0 ) diff --git a/go.sum b/go.sum index 22aee209c6..a18c395579 100644 --- a/go.sum +++ b/go.sum @@ -11,16 +11,16 @@ github.com/richardlehane/msoleps v1.0.3 h1:aznSZzrwYRl3rLKRT3gUk9am7T/mLNSnJINvN github.com/richardlehane/msoleps v1.0.3/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53 h1:Chd9DkqERQQuHpXjR/HSV1jLZA6uaoiwwH3vSuF3IW0= -github.com/xuri/efp v0.0.0-20231025114914-d1ff6096ae53/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d h1:llb0neMWDQe87IzJLS4Ci7psK/lVsjIS2otl+1WyRyY= +github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d/go.mod h1:ybY/Jr0T0GTCnYjKqmdwxyxn2BQf2RcQIIvex5QldPI= github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A= github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4= golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= -golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=