From c04b6b0a20c17ffbfa799178b2cb1457e4bf510b Mon Sep 17 00:00:00 2001 From: Attila Kovacs Date: Sun, 17 Nov 2024 16:59:11 +0100 Subject: [PATCH] make_object() to remain safe for objects compiled with older version of the `object` structure. --- include/novas.h | 2 +- src/novas.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/novas.h b/include/novas.h index 8b238f1c..4a85b5d1 100644 --- a/include/novas.h +++ b/include/novas.h @@ -803,7 +803,7 @@ typedef struct { long number; ///< enum novas_planet, or minor planet ID (e.g. NAIF), or star catalog ID. char name[SIZE_OF_OBJ_NAME]; ///< name of the object (0-terminated) cat_entry star; ///< basic astrometric data for NOVAS_CATALOG_OBJECT type. - novas_orbital_elements orbit; ///< orbital data for NOVAS_ORBITAL_OBJECT TYPE. @since 1.2 + novas_orbital_elements orbit; ///< orbital data for NOVAS_ORBITAL_OBJECT type. @since 1.2 } object; /** diff --git a/src/novas.c b/src/novas.c index 008d876f..587e36b8 100644 --- a/src/novas.c +++ b/src/novas.c @@ -21,6 +21,7 @@ #include #include #include // stdarg.h before stdio.h (for older gcc...) +#include #if !COMPAT # include @@ -6715,6 +6716,13 @@ void novas_case_sensitive(int value) { * compatibility with NOVAS C) source names are converted to upper-case internally. You can * however enable case-sensitive processing by calling novas_case_sensitive() before. * + * NOTES: + *
    + *
  1. This call does not initialize the `orbit` field (added in v1.2) with zeroes to remain ABI + * compatible with versions <1.2, and to avoid the possiblity of segfaulting if used to + * initialize a legacy `object` variable.
  2. + *
+ * * @param type The type of object. NOVAS_PLANET (0), NOVAS_EPHEM_OBJECT (1) or * NOVAS_CATALOG_OBJECT (2), or NOVAS_ORBITAL_OBJECT (3). * @param number The novas ID number (for solar-system bodies only, otherwise ignored) @@ -6746,7 +6754,8 @@ short make_object(enum novas_object_type type, long number, const char *name, co if(!source) return novas_error(-1, EINVAL, fn, "NULL input source"); - memset(source, 0, sizeof(*source)); + // FIXME for version v2.x initialize the entire structure again... + memset(source, 0, offsetof(object, orbit)); // Set the object type. if(type < 0 || type >= NOVAS_OBJECT_TYPES) @@ -6759,6 +6768,10 @@ short make_object(enum novas_object_type type, long number, const char *name, co if(number < 0 || number >= NOVAS_PLANETS) return novas_error(2, EINVAL, fn, "planet number %ld is out of bounds [0:%d]", number, NOVAS_PLANETS - 1); + // FIXME will not need special case in v2.x + if(type == NOVAS_ORBITAL_OBJECT) + memset(&source->orbit, 0, sizeof(source->orbit)); + source->number = number; if(name) {