Modify

Opened 8 months ago

Last modified 6 weeks 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 8 months ago by Jos

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).

Last edited 8 months ago by Jos (previous) (diff)

comment:2 Changed 8 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 8 months ago by Jos

True... so something is broken.....

comment:4 Changed 8 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 8 months ago by Jpm

  • Owner set to Jpm
  • Status changed from new to assigned

Thanks Fix sent to Jon

comment:6 Changed 7 months ago by jchd18

See also ticket #3976 about the exact same issue with StringRegExp.

comment:7 Changed 6 weeks 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.

Add Comment

Modify Ticket

Action
as assigned The owner will remain Jon.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.