Opened 15 months ago
Last modified 8 months ago
#3972 assigned Bug
StringSplit can create invalid Arrays
Reported by: | anonymous | Owned by: | Jon |
---|---|---|---|
Milestone: | Component: | AutoIt | |
Version: | 3.3.16.1 | Severity: | None |
Keywords: | Cc: |
Description
Global $s = ' ' For $i = 0 To 24 Step 1 $s = $s & $s Next ; String is now 33554432 symbols long Global $a = StringSplit($s, '') ; Also works with flags 1, 2 and 3. If count is in [0], UBound correctly shows 33554433. Global $err = @error, $ext = @extended ConsoleWrite('@error = ' & $err & @CRLF) ; @error is not set, because delimiters were indeed found ConsoleWrite('@extended = ' & $ext & @CRLF) ; Just to be sure it is also 0. ConsoleWrite('VarGetType = ' & VarGetType($a) & @CRLF) ; It is an array ConsoleWrite('UBound = ' & UBound($a) & @CRLF) ; UBound works (propably because Array-Metadata are set before the array is filled, I don't know the code so this is guesswork) ConsoleWrite($a[0] & @CRLF) ; This will fail -> Array variable has incorrect number of subscripts or subscript dimension range exceeded
Attachments (0)
Change History (7)
comment:1 Changed 15 months ago by Jos
comment:2 Changed 15 months ago by AspirinJunkie
The help also states:
If you use an empty string "" for the delimiters, each character will be returned as an element.
I strongly suggest not touching this behavior. First, it would be script breaking for a lot of scripts that use StringSplit to split a string into an array of characters and second, it doesn't fix the bug described here, since it also occurs with a delimiter with one or more characters:
Global $s = ' ' For $i = 0 To 24 Step 1 $s = $s & ";" & $s Next ConsoleWrite(StringLen($s) & @CRLF) ; String is now 33,554,432 symbols long with 33,554,431 delimiters Global $a = StringSplit($s, ';') ; Also works with flags 1, 2 and 3. If count is in [0], UBound correctly shows 33554433. Global $err = @error, $ext = @extended ConsoleWrite('@error = ' & $err & @CRLF) ; @error is not set, because delimiters were indeed found ConsoleWrite('@extended = ' & $ext & @CRLF) ; Just to be sure it is also 0. ConsoleWrite('VarGetType = ' & VarGetType($a) & @CRLF) ; It is an array ConsoleWrite('UBound = ' & UBound($a) & @CRLF) ; UBound works (propably because Array-Metadata are set before the array is filled, I don't know the code so this is guesswork) ConsoleWrite($a[0] & @CRLF) ; This will fail -> Array variable has incorrect number of subscripts or subscript dimension range exceeded
The behavior also differs between AutoIt versions. Under version 3.14.5 the script crashes when StringSplit is called. I have not tested other versions.
comment:3 Changed 15 months ago by Jos
True... so something is broken.....
comment:4 Changed 15 months ago by AspirinJunkie
The problem is obviously that StringSplit would create an array with more elements than the maximum number of array elements possible in AutoIt (VAR_SUBSCRIPT_ELEMENTS = 16,777,216):
#include "String.au3" $s = _StringRepeat(' ', 16777215) ; change to 16777216 to see the effect Global $a = StringSplit($s, '') ConsoleWrite(StringFormat("@error: %s\n@extended: %\nVargetType: %s\nUbound: %d\n", _ @error, @extended, VarGetType($a), UBound($a))) ConsoleWrite($a[0] & @CRLF)
So basically all that is missing is another query in StringSplit that catches this case and then sets @error in it and returns either an empty array or a truncated array.
comment:5 Changed 15 months ago by Jpm
- Owner set to Jpm
- Status changed from new to assigned
Thanks Fix sent to Jon
comment:6 Changed 14 months ago by jchd18
See also ticket #3976 about the exact same issue with StringRegExp.
comment:7 Changed 8 months ago by Jpm
- Owner changed from Jpm to Jon
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Guess a check for the second parameter would be appropriate to ensure it has a length of 1 or more.
The helpfile does state:
delimiters One or more characters to use as delimiters (case sensitive).