Skip to content

Commit af59c6b

Browse files
github-actions[bot]MangelMaximeclaude
authored
[JS/TS] Fix ResizeArray index getter/setter not throwing IndexOutOfRangeException when index is out of bounds
Co-authored-by: Mangel Maxime <me@mangelmaxime.fr> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent df5a43c commit af59c6b

5 files changed

Lines changed: 23 additions & 10 deletions

File tree

src/Fable.Cli/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
* [TS] Annotate `System.Collections.Generic.IList<T>` as `MutableArray<T>` (by @MangelMaxime)
13+
* [JS/TS] Fix `ResizeArray` index getter/setter not throwing `IndexOutOfRangeException` when index is out of bounds (fix #3812) (by @MangelMaxime)
1214
* [Beam] Fix unused term warning in try/catch when exception variable is not referenced (by @dbrattli)
1315
* [Beam] Fix "no effect" warning for pure BIF calls (`self/0`, `node/0`) in non-final block positions (by @dbrattli)
1416
* [Beam] Fix `reraise()` generating unbound `MatchValue` variable — use raw Erlang reason variable for re-throw (by @dbrattli)

src/Fable.Compiler/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Fixed
1111

12+
* [TS] Annotate `System.Collections.Generic.IList<T>` as `MutableArray<T>` (by @MangelMaxime)
13+
* [JS/TS] Fix `ResizeArray` index getter/setter not throwing `IndexOutOfRangeException` when index is out of bounds (fix #3812) (by @MangelMaxime)
1214
* [Beam] Fix unused term warning in try/catch when exception variable is not referenced (by @dbrattli)
1315
* [Beam] Fix "no effect" warning for pure BIF calls (`self/0`, `node/0`) in non-final block positions (by @dbrattli)
1416
* [Beam] Fix `reraise()` generating unbound `MatchValue` variable — use raw Erlang reason variable for re-throw (by @dbrattli)

src/Fable.Transforms/Fable2Babel.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -815,6 +815,7 @@ module Annotation =
815815
| Types.iobservableGeneric ->
816816
makeFableLibImportTypeAnnotation com ctx genArgs "Observable" "IObservable"
817817
|> Some
818+
| Types.ilistGeneric -> makeFableLibImportTypeAnnotation com ctx genArgs "Util" "MutableArray" |> Some
818819
| "Microsoft.FSharp.Control.IEvent`1" ->
819820
makeFableLibImportTypeAnnotation com ctx genArgs "Event" "IEvent" |> Some
820821
| Types.ievent2 -> makeFableLibImportTypeAnnotation com ctx genArgs "Event" "IEvent$2" |> Some

src/Fable.Transforms/Replacements.fs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1921,8 +1921,9 @@ let resizeArrays (com: ICompiler) (ctx: Context) r (t: Type) (i: CallInfo) (this
19211921
Helper.GlobalCall("Array", t, args, memb = "from", ?loc = r)
19221922
|> withTag "array"
19231923
|> Some
1924-
| "get_Item", Some ar, [ idx ] -> getExpr r t ar idx |> Some
1925-
| "set_Item", Some ar, [ idx; value ] -> setExpr r ar idx value |> Some
1924+
| "get_Item", Some ar, [ idx ] -> Helper.LibCall(com, "Array", "item", t, [ idx; ar ], ?loc = r) |> Some
1925+
| "set_Item", Some ar, [ idx; value ] ->
1926+
Helper.LibCall(com, "Array", "setItem", t, [ ar; idx; value ], ?loc = r) |> Some
19261927
| "CopyTo", Some ar, [ target ] ->
19271928
let count = getFieldWith r t ar "length"
19281929
copyToArray com r t i [ ar; makeIntConst 0; target; makeIntConst 0; count ]

tests/Js/Main/ResizeArrayTests.fs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ module Fable.Tests.ResizeArrays
22

33
open System.Collections.Generic
44
open Util.Testing
5+
open Fable.Tests.Util
56

67
type Animal = Duck of int | Dog of int
78

@@ -264,14 +265,9 @@ let tests =
264265
equal 3. li.[0]
265266
equal 2. ar.[0]
266267

267-
testCase "ResizeArray.Item is undefined when index is out of range" <| fun () ->
268+
testCase "ResizeArray.Item throws on out of bounds access" <| fun _ ->
268269
let xs = ResizeArray [0]
269-
#if FABLE_COMPILER
270-
isNull <| box (xs.Item 1)
271-
#else
272-
try (xs.Item 1) |> ignore; false with _ -> true
273-
#endif
274-
|> equal true
270+
throwsAnyError (fun () -> xs.Item 1 |> ignore)
275271

276272
testCase "ResizeArray.Remove works with non-primitive types" <| fun _ ->
277273
let myResizeArray = new ResizeArray<Animal>()
@@ -369,4 +365,15 @@ let tests =
369365
coll.Remove(("D", 3)) |> equal false
370366
coll.Remove(("B", 2)) |> equal true
371367
coll.Count |> equal 2
372-
]
368+
369+
testCase "ResizeArray index out of bounds get throws" <| fun _ -> // See #3812
370+
let xs = ResizeArray [1; 2; 3]
371+
throwsAnyError (fun () -> xs[-1] |> ignore)
372+
throwsAnyError (fun () -> xs[10] |> ignore)
373+
374+
375+
testCase "ResizeArray index out of bounds set throws" <| fun _ -> // See #3812
376+
let xs = ResizeArray [1; 2; 3]
377+
throwsAnyError (fun () -> xs.[-1] <- 42)
378+
throwsAnyError (fun () -> xs.[10] <- 42)
379+
]

0 commit comments

Comments
 (0)