Skip to content

Bad conversion of NULL when passing integer vector #1564

@szhorvat

Description

@szhorvat

When passing an integer vector from R to C, the NULL value is converted to an empty vector.

This is the ultimate cause of the UBSan failure that CRAN caught,

> sample_motifs(g, 3)
vendor/cigraph/src/misc/motifs.c:719:12: runtime error: -nan is outside the range of representable values of type 'long'
    #0 0x7fdade541593 in igraph_motifs_randesu_estimate /data/gannet/ripley/R/packages/tests-clang-UBSAN/igraph/src/vendor/cigraph/src/misc/motifs.c:719:12
    #1 0x7fdadde7184f in R_igraph_motifs_randesu_estimate /data/gannet/ripley/R/packages/tests-clang-UBSAN/igraph/src/rinterface.c:8689:3
    #2 0x55ea33fe822a in R_doDotCall (/data/gannet/ripley/R/R-clang/bin/exec/R+0xf122a)
    #3 0x55ea34030024 in bcEval_loop eval.c
    #4 0x55ea3401f39b in bcEval eval.c
    #5 0x55ea3401eb24 in Rf_eval (/data/gannet/ripley/R/R-clang/bin/exec/R+0x127b24)
    #6 0x55ea34042141 in R_execClosure eval.c
    #7 0x55ea3404162b in applyClosure_core eval.c
    #8 0x55ea3401ef75 in Rf_eval (/data/gannet/ripley/R/R-clang/bin/exec/R+0x127f75)
    #9 0x55ea34076b00 in Rf_ReplIteration (/data/gannet/ripley/R/R-clang/bin/exec/R+0x17fb00)
    #10 0x55ea3407849e in run_Rmainloop (/data/gannet/ripley/R/R-clang/bin/exec/R+0x18149e)
    #11 0x55ea3407850a in Rf_mainloop (/data/gannet/ripley/R/R-clang/bin/exec/R+0x18150a)
    #12 0x55ea33f5e947 in main (/data/gannet/ripley/R/R-clang/bin/exec/R+0x67947)
    #13 0x7fdaeee2950f in __libc_start_call_main (/lib64/libc.so.6+0x2950f) (BuildId: 8257ee907646e9b057197533d1e4ac8ede7a9c5c)
    #14 0x7fdaeee295c8 in __libc_start_main@GLIBC_2.2.5 (/lib64/libc.so.6+0x295c8) (BuildId: 8257ee907646e9b057197533d1e4ac8ede7a9c5c)
    #15 0x55ea33f5e864 in _start (/data/gannet/ripley/R/R-clang/bin/exec/R+0x67864)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior vendor/cigraph/src/misc/motifs.c:719:12 
[1] -9.223372e+18

It's not just an UBSan warning. sample_motifs() is essentially broken, and likely so are some other functions that take optional integer vectors.

In rinterface.c, I see this:

  if (!Rf_isNull(sample)) {
    R_SEXP_to_vector_int_copy(sample, &c_sample);
    IGRAPH_FINALLY(igraph_vector_int_destroy, &c_sample);
  } else {
    IGRAPH_R_CHECK(igraph_vector_int_init(&c_sample, 0));
    IGRAPH_FINALLY(igraph_vector_int_destroy, &c_sample);
  }

It should produce a NULL pointer instead of an empty vector.

This should be changed, but be aware that doing so may cause issues elsewhere, which will need to be fixed as well.

I don't see the null check in types-RC.yaml, so I assume it comes directly from Stimulus. Can you have a look, @Antonov548 ?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugan unexpected problem or unintended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions