summaryrefslogtreecommitdiff
path: root/wizards
diff options
context:
space:
mode:
authorJean-Pierre Ledure <jp@ledure.be>2022-06-26 16:30:11 +0200
committerJean-Pierre Ledure <jp@ledure.be>2022-06-26 17:17:53 +0200
commite58a75251a4c877ff4ded94ede01310135b996db (patch)
tree5d1f7cb3bd9b8f7557fc5b6fd01e0cc7b53b1019 /wizards
parente021fc0a1a00f4ac635cdbeb89826805482e50df (diff)
ScriptForge - (SF_Calc) accurate sheet name check
The parsing of sheet names and range addresses has been reviewed to include the exact rules for sheet naming: must not be empty must not contain []*?:/\ must not use ' (apostrophe) as 1st and last character Additionally (ScriptForge only) it must not contain "~" which, by convention, indicates the active sheet. The code accepts exotic sheet names like: "$" "$Sheet99" "$Sheet'99" "$.Sheet'99" "!'@#$%^&()-_=+{}|;,<.>""" and exotic addresses like: "'$'.A1" "'$Sheet99'.A1" "'$Sheet''99'.A1" "'$.Sheet''99'.A1" "'!''@#$%^&()-_=+{}|;,<.>""'.A1" Target is to match completely the Calc constraints for writing formulas and sheet names.. The same rules are applicable evenly for user scripts written either in Basic or in Python. Change-Id: I759d7700152a3d811b89f156c4d9eee0071c2a7e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136446 Tested-by: Jean-Pierre Ledure <jp@ledure.be> Reviewed-by: Jean-Pierre Ledure <jp@ledure.be> Tested-by: Jenkins
Diffstat (limited to 'wizards')
-rw-r--r--wizards/source/scriptforge/SF_Exception.xba2
-rw-r--r--wizards/source/sfdocuments/SF_Calc.xba73
-rw-r--r--wizards/source/sfdocuments/SF_Document.xba3
3 files changed, 53 insertions, 25 deletions
diff --git a/wizards/source/scriptforge/SF_Exception.xba b/wizards/source/scriptforge/SF_Exception.xba
index 11e97b02b753..572b0fb950a6 100644
--- a/wizards/source/scriptforge/SF_Exception.xba
+++ b/wizards/source/scriptforge/SF_Exception.xba
@@ -962,7 +962,7 @@ Try:
pvArgs(0) = _RightCase(pvArgs(0)) : pvArgs(2) = _RightCase(pvArgs(2))
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
- &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CALCADDRESS&quot; &amp; Iif(pvArgs(0) = &quot;Sheet&quot;, &quot;1&quot;, &quot;2&quot;), pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
+ &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;CALCADDRESS&quot; &amp; Iif(Left(pvArgs(0), 5) = &quot;Sheet&quot;, &quot;1&quot;, &quot;2&quot;), pvArgs(0), pvArgs(1), pvArgs(2), pvArgs(3))
Case DUPLICATESHEETERROR &apos; SF_Calc.InsertSheet(arg, SheetName, Document)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
diff --git a/wizards/source/sfdocuments/SF_Calc.xba b/wizards/source/sfdocuments/SF_Calc.xba
index 0b7b88ae8f76..57d3d0fb63cf 100644
--- a/wizards/source/sfdocuments/SF_Calc.xba
+++ b/wizards/source/sfdocuments/SF_Calc.xba
@@ -127,7 +127,7 @@ Private Const SERVICEREFERENCE = &quot;SFDocuments.CalcReference&quot;
Private Const ISCALCFORM = 2 &apos; Form is stored in a Calc document
-Private Const cstSPECIALCHARS = &quot; `~!@#$%^&amp;()-_=+{}|;:,&lt;.&gt;&quot;&quot;&quot;
+Private Const cstSPECIALCHARS = &quot; `~!@#$%^&amp;()-_=+{}|;,&lt;.&gt;&quot;&quot;&quot;
&apos; Presence of a special character forces surrounding the sheet name with single quotes in absolute addresses
@@ -4080,6 +4080,7 @@ Private Function _ParseAddress(ByVal psAddress As String) As Object
Dim oAddress As Object &apos; Return value
Dim sAddress As String &apos; Alias of psAddress
+Dim vRangeName As Variant &apos; Array Sheet/Range
Dim lStart As Long &apos; Position of found regex
Dim sSheet As String &apos; Sheet component
Dim sRange As String &apos; Range component
@@ -4112,23 +4113,17 @@ Dim oSelect As Object &apos; Current selection
.RawAddress = psAddress
Set .XSpreadSheet = Nothing : Set .XCellRange = Nothing
- &apos; Remove leading &apos;$&apos;
- If Left(psAddress, 1) = &quot;$&quot; Then sAddress = Mid(psAddress, 2) Else sAddress = psAddress
- &apos; Split in sheet and range components - Check presence of surrounding single quotes or dot
- If Left(sAddress, 1) = &quot;&apos;&quot; Then
- lStart = 1
- sSheet = ScriptForge.SF_String.FindRegex(sAddress, &quot;^&apos;[^\[\]*?:\/\\]+&apos;&quot;)
- If lStart = 0 Then GoTo CatchAddress &apos; Invalid sheet name
- If Len(sAddress) &gt; Len(sSheet) + 1 Then
- If Mid(sAddress, Len(sSheet) + 1, 1) = &quot;.&quot; then sRange = Mid(sAddress, Len(sSheet) + 2)
- End If
- sSheet = Replace(Replace(sSheet, &quot;$&quot;, &quot;&quot;), &quot;&apos;&quot;, &quot;&quot;)
- ElseIf InStr(sAddress, &quot;.&quot;) &gt; 0 Then
- sSheet = Replace(Split(sAddress, &quot;.&quot;)(0), &quot;$&quot;, &quot;&quot;)
- sRange = Replace(Split(sAddress, &quot;.&quot;)(1), &quot;$&quot;, &quot;&quot;)
- Else
- sSheet = sAddress
- End If
+ &apos; Remove leading &quot;$&apos; when followed with an apostrophe
+ If Left(psAddress, 2) = &quot;$&apos;&quot; Then sAddress = Mid(psAddress, 2) Else sAddress = psAddress
+ &apos; Split in sheet and range components on dot not enclosed in single quotes
+ vRangeName = ScriptForge.SF_String.SplitNotQuoted(sAddress, Delimiter := &quot;.&quot;, QuoteChar := &quot;&apos;&quot;)
+ sSheet = ScriptForge.SF_String.Unquote(Replace(vRangeName(0), &quot;&apos;&apos;&quot;, &quot;\&apos;&quot;), QuoteChar := &quot;&apos;&quot;)
+ &apos; Keep a leading &quot;$&quot; in the sheet name only if name enclosed in single quotes
+ &apos; Notes:
+ &apos; sheet names may contain &quot;$&quot; (even &quot;$&quot; is a valid sheet name), named ranges must not
+ &apos; sheet names may contain apostrophes (except in 1st and last positions), range names must not
+ If Left(vRangeName(0), 2) &lt;&gt; &quot;&apos;$&quot; And Left(sSheet, 1) = &quot;$&quot; And Len(sSheet) &gt; 1 Then sSheet = Mid(sSheet, 2)
+ If UBound(vRangeName) &gt; 0 Then sRange = vRangeName(1)
&apos; Resolve sheet part: either a document named range, or the active sheet or a real sheet
Set oSheets = _Component.getSheets()
@@ -4444,7 +4439,6 @@ Private Function _ValidateSheet(Optional ByRef pvSheetName As Variant _
&apos;&apos;&apos; DUPLICATESHEETERROR A sheet with the given name exists already
Dim vSheets As Variant &apos; List of sheets
-Dim sSheet As String &apos; Sheet name without single quotes
Dim lSheet As Long &apos; Index in list of sheets
Dim vTypes As Variant &apos; Array of accepted variable types
Dim bValid As Boolean &apos; Return value
@@ -4475,13 +4469,13 @@ Try:
pvSheetName = _Component.CurrentController.ActiveSheet.Name
Else
vSheets = _Component.getSheets.getElementNames()
- sSheet = Replace(pvSheetName, &quot;&apos;&quot;, &quot;&quot;)
If pvNew Then
- If ScriptForge.SF_Array.Contains(vSheets, sSheet) Then GoTo CatchDuplicate
+ &apos; ScriptForge.SF_String.FindRegex(sAddress, &quot;^&apos;[^\[\]*?:\/\\]+&apos;&quot;)
+ If ScriptForge.SF_Array.Contains(vSheets, pvSheetName) Then GoTo CatchDuplicate
Else
- If Not ScriptForge.SF_Utils._Validate(sSheet, psArgName, V_STRING, vSheets) Then GoTo Finally
+ If Not ScriptForge.SF_Utils._Validate(pvSheetName, psArgName, V_STRING, vSheets) Then GoTo Finally
If pvResetSheet Then
- lSheet = ScriptForge.SF_Array.IndexOf(vSheets, sSheet, CaseSensitive := False)
+ lSheet = ScriptForge.SF_Array.IndexOf(vSheets, pvSheetName, CaseSensitive := False)
pvSheetName = vSheets(lSheet)
End If
End If
@@ -4497,5 +4491,38 @@ CatchDuplicate:
GoTo Finally
End Function &apos; SFDocuments.SF_Calc._ValidateSheet
+REM -----------------------------------------------------------------------------
+Private Function _ValidateSheetName(ByRef psSheetName As String _
+ , ByVal psArgName As String _
+ ) As Boolean
+&apos;&apos;&apos; Check the validity of the sheet name:
+&apos;&apos;&apos; A sheet name - must not be ampty
+&apos;&apos;&apos; - must not contain next characters: []*?:/\
+&apos;&apos;&apos; - must not use &apos; (the apostrophe) as first or last character
+&apos;&apos;&apos; Args:
+&apos;&apos;&apos; psSheetName: the name to check
+&apos;&apos;&apos; psArgName: the name of the argument to appear in error messages
+&apos;&apos;&apos; Returns:
+&apos;&apos;&apos; True when the sheet name is valid
+&apos;&apos;&apos; Exceptions:
+&apos;&apos;&apos; CALCADDRESSERROR &apos; Sheet name could not be parsed to a valid name
+
+Dim bValid As Boolean &apos; Return value
+
+Try:
+ bValid = ( Len(psSheetName) &gt; 0 )
+ If bValid Then bValid = ( Left(psSheetName, 1) &lt;&gt; &quot;&apos;&quot; And Right(psSheetName, 1) &lt;&gt; &quot;&apos;&quot; )
+ If bValid Then bValid = ( Len(ScriptForge.SF_String.FindRegex(psSheetName, &quot;^[^\[\]*?:\/\\]+$&quot;, 1, CaseSensitive := False)) &gt; 0 )
+ If Not bValid Then GoTo CatchSheet
+
+Finally:
+ _ValidateSheetName = bValid
+ Exit Function
+CatchSheet:
+ ScriptForge.SF_Exception.RaiseFatal(CALCADDRESSERROR, psArgName, psSheetName _
+ , &quot;Document&quot;, [_Super]._FileIdent())
+ GoTo Finally
+End Function &apos; SFDocuments.SF_Calc._ValidateSheetName
+
REM ============================================ END OF SFDOCUMENTS.SF_CALC
</script:module> \ No newline at end of file
diff --git a/wizards/source/sfdocuments/SF_Document.xba b/wizards/source/sfdocuments/SF_Document.xba
index c5440944584d..7c9991124d63 100644
--- a/wizards/source/sfdocuments/SF_Document.xba
+++ b/wizards/source/sfdocuments/SF_Document.xba
@@ -1279,7 +1279,8 @@ Private Function _FileIdent() As String
&apos;&apos;&apos; Returns a file identification from the information that is currently available
&apos;&apos;&apos; Useful e.g. for display in error messages
- _FileIdent = Iif(Len(_WindowFileName) &gt; 0, SF_FileSystem._ConvertFromUrl(_WindowFileName), _WindowTitle)
+ &apos; OS notation is used to avoid presence of &quot;%nn&quot; in error messages and wrong parameter substitutions
+ _FileIdent = Iif(Len(_WindowFileName) &gt; 0, ConvertFromUrl(_WindowFileName), _WindowTitle)
End Function &apos; SFDocuments.SF_Document._FileIdent