agrafix / agrafix/superrecord

!!! `project` causes memory inconsistencies

Offen
#38 10 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
Vorherrschende Sprache
Haskell
Sterne
83
Forks
16
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

`project` (and potentially also `inject`, we haven’t verified`, will cause undefined behavior, which we noticed & verified in a production system.

*The bug only appears with optimizations enabled (only tested `-O2`), not in ghci*

I don’t have a minimal repro (yet), but I can describe what we did:

There was one function which loaded some data in `IO`, constructed a ist of `rec`, then before returning used `project` to reduce unnecessary fields in every list element:

```haskell
loadData :: IO (Record '[ "foo" := Text ])
loadData = do
listOfRes <-
pure
$ map
(project @'["foo" := Text, "bar" := Int] @'["foo" := Text])
listOfRes
```

And another function that pulled *a subset* of fields from the record, like this:

```haskell
requestBody = do
dat <- loadData

let mapDat d = (Json.object [
("foo", get #foo d)
])

pure $ Json.Array (map mapDat dat)
```

Let’s say the final data was

```haskell
[
{ foo = "xx" },
{ foo = "yy" },
{ foo = "zz" },
]
```

Then what would be actually returned was (!!):

```haskell
[
{ foo = "xx" },
{ foo = "xx" },
{ foo = "xx" },
]
```

now, if you rewrote the function to deeply evaluate the `project`ed record:

```haskell
loadData :: IO (Record '[ "foo" := Text ])
loadData = do
listOfRes <-

print listOfRes -- <- deeply evaluate the record by printing it

pure
$ map
(project @'["foo" := Text, "bar" := Int] @'["foo" := Text])
listOfRes
```

It would again return

```haskell
[
{ foo = "xx" },
{ foo = "yy" },
{ foo = "zz" },
]
```

When we rewrote the original function to construct a new record instead of `project`ing:

```haskell
loadData :: IO (Record '[ "foo" := Text ])
loadData = do
listOfRes <-
pure
$ map
(\res -> rcons #foo (get #foo res) rnil)
listOfRes
```

The problem went away.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Bewertung

Dieses Issue wurde noch nicht bewertet.

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.