coolbutuseless / yyjsonr

Fast JSON package for R
https://coolbutuseless.github.io/package/yyjsonr/index.html
Other
124 stars 8 forks source link

Crash with factors and write_json_str #35

Closed mattjvincent closed 6 months ago

mattjvincent commented 6 months ago

yyjsonr will cause a fatal error when a variable is declared as a factor, but the values do not match the specified levels.

The following example will crash the R session.

> color <- c("red", "blue", NA, "red", "white")
> color <- factor(color, levels=c("red", "blue"))
> color
[1] red  blue <NA> red  <NA>
Levels: red blue
> color_str <- yyjsonr::write_json_str(color)

I also tried with a tibble.

> tbl <- tibble::tribble(
    ~unique_id, ~name,  ~color,
    1,          "fred", "red",
    2,          "sue",  "blue",
    3,          "mary", NA,
    4,          "joe",  "red"
)
> tbl
# A tibble: 4 × 3
  unique_id name  color
      <dbl> <chr> <chr>
1         1 fred  red  
2         2 sue   blue 
3         3 mary  NA   
4         4 joe   red  
> tbl$color <- factor(tbl$color, levels=c("red", "blue"))
> tbl_str <- yyjsonr::write_json_str(tbl)

Crashed on both Mac (M1, Sonoma) and Linux Rocky 9.

coolbutuseless commented 6 months ago

Thanks @mattjvincent !

This error occurred because within C I was doing the equivalent of names(this_factor)[NA] which attempts an out-of-bounds access to the names of the factor.

Fixed in https://github.com/coolbutuseless/yyjsonr/commit/431cca9cda350e5e4f7ab9ed2802a141a0013cb4