Skip to content

Ensure indirect function calls have the correct type.#1994

Open
daviesrob wants to merge 1 commit intosamtools:developfrom
daviesrob:function-pointers
Open

Ensure indirect function calls have the correct type.#1994
daviesrob wants to merge 1 commit intosamtools:developfrom
daviesrob:function-pointers

Conversation

@daviesrob
Copy link
Copy Markdown
Member

Some HTSlib interfaces (notably kgetline(), kgetline2(), hts_itr_querys() and hts_parse_region()) have function callbacks that are intended to be generic, so the function signatures include a void * for data to be passed in. E.g. for kgetline() this would be the FILE * or hFILE * to read. Historically they have often been called with a function that has an explicit type (e.g. FILE * for fgets() used with kgetline) on the assumption that casting it to void * is harmless. Unfortunately doing this is strictly undefined behaviour and will fail in some conditions - for example if compiling with control flow integrity turned on. Recent versions of clang will also call this out when using undefined behaviour sanitizer. The solution is to create wrapper functions that do take a void *, and call the intended function with suitable casts.

Some new interfaces are also added so that the messy implementation details can be hidden away, and the inputs can be better type checked. Hopefully this should also allow the wrapper functions to be inlined away.

  • hget_kstr() to read lines from an hFILE * to a kstring.

  • kgetline() to read lines from a FILE * to a kstring.

  • tbx_itr_querys1() to create a tabix iterator on a region. Used to reimplement the existing tbx_itr_querys() macro.

  • bcf_itr_querys1() to create a region iterator an a bcf file Used to reimplement the existing bcf_itr_querys() macro.

Some HTSlib interfaces (notably kgetline(), kgetline2(),
hts_itr_querys() and hts_parse_region()) have function
callbacks that are intended to be generic, so the
function signatures include a `void *` for data to
be passed in.  E.g. for kgetline() this would be the
FILE * or hFILE * to read.  Historically they have
often been called with a function that has an explicit
type (e.g. FILE * for fgets() used with kgetline)
on the assumption that casting it to void * is harmless.
Unfortunately doing this is strictly undefined behaviour
and will fail in some conditions - for example if
compiling with control flow integrity turned on.  Recent
versions of clang will also call this out when using
undefined behaviour sanitizer.  The solution is to create
wrapper functions that do take a void *, and call the
intended function with suitable casts.

Some new interfaces are also added so that the
messy implementation details can be hidden away,
and the inputs can be better type checked. Hopefully
this should also allow the wrapper functions to be
inlined away.

 * hget_kstr() to read lines from an hFILE * to a kstring.

 * kgetline() to read lines from a FILE * to a kstring.

 * tbx_itr_querys1() to create a tabix iterator on a region.
   Used to reimplement the existing tbx_itr_querys() macro.

 * bcf_itr_querys1() to create a region iterator an a bcf file
   Used	to reimplement the existing bcf_itr_querys() macro.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants