diff --git a/CHANGELOG.md b/CHANGELOG.md index 1acb345a..24f9de39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), Release candidate for the next feature release, expected around 1 February 2025. +### Fixed + + - `make_on_surface()` to leave humidity undefined. The `humidity` field was added in v1.1 only, and thus attempting + to initialize it to zero can use memory corruption or even segfaulting if called by objects that have been compiled + with v1.0. So, from now on the call will leave humidity uninitialized and it's up to the calle ro define it if it + is needed for the specific refraction model. + ### Added - #57: New `novas_make_redshifted_object()` to simplify the creation of distant catalog sources that are diff --git a/include/novas.h b/include/novas.h index 4a85b5d1..d1fd7dbe 100644 --- a/include/novas.h +++ b/include/novas.h @@ -807,14 +807,12 @@ typedef struct { } object; /** - * data for an observer's location on the surface of - * the Earth. The atmospheric parameters are used - * only by the refraction function called from - * function 'equ2hor'. Additional parameters can be - * added to this structure if a more sophisticated - * refraction model is employed. + * Data for an observer's location on the surface of the Earth, and optional local weather data for + * refraction calculations only. * * @sa observer + * @sa make_on_surface() + * @sa ON_SURFACE_INIT */ typedef struct { double latitude; ///< [deg] geodetic (ITRS) latitude; north positive @@ -825,11 +823,20 @@ typedef struct { double humidity; ///< [%] Relative humidity. @since 1.1 } on_surface; +/** + * Initialized for a NOVAS on_surface data structure. + * + * @sa on_surface + * @since 1.2 + */ +#define ON_SURFACE_INIT { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 } + /** * data for an observer's location on Earth orbit * * @sa observer * @sa IN_SPACE_INIT + * @sa make_in_space() */ typedef struct { double sc_pos[3]; ///< [km] geocentric (or [AU] ICRS barycentric) position vector (x, y, z) @@ -846,6 +853,11 @@ typedef struct { /** * Observer location. * + * @sa make_observer() + * @sa make_observer_at_geocenter() + * @sa make_observer_on_earth() + * @sa make_observer_in_space() + * @sa make_solar_system_observer() */ typedef struct { enum novas_observer_place where; ///< observer location type @@ -860,6 +872,7 @@ typedef struct { in_space near_earth; } observer; + /** * Celestial object's place on the sky; contains the output from place() * diff --git a/src/novas.c b/src/novas.c index 587e36b8..7252bc65 100644 --- a/src/novas.c +++ b/src/novas.c @@ -6840,6 +6840,7 @@ int make_planet(enum novas_planet num, object *planet) { * @sa make_observer_at_geocenter() * @sa make_observer_on_surface() * @sa make_observer_in_space() + * @sa make_solar_system_observer() */ short make_observer(enum novas_observer_place where, const on_surface *loc_surface, const in_space *loc_space, observer *obs) { static const char *fn = "make_observer"; @@ -6956,9 +6957,9 @@ int make_observer_in_space(const double *sc_pos, const double *sc_vel, observer * the given parameters. * * Note, that because this is an original NOVAS C routine, it does not have an argument to set - * a humidity value (e.g. for radio refraction). As such the call will set humidity to 0.0. - * To set the humidity, set the output structure's field after calling this funcion. Its unit - * is [%], and so the range is 0.0--100.0. + * a humidity value (e.g. for radio refraction). As such, the humidity value remains undefined + * after this call. To set the humidity, set the output structure's field after calling this + * funcion. Its unit is [%], and so the range is 0.0--100.0. * * @param latitude [deg] Geodetic (ITRS) latitude in degrees; north positive. * @param longitude [deg] Geodetic (ITRS) longitude in degrees; east positive. @@ -6981,7 +6982,9 @@ int make_on_surface(double latitude, double longitude, double height, double tem loc->height = height; loc->temperature = temperature; loc->pressure = pressure; - loc->humidity = 0.0; + + // FIXME starting v2.0 set humidity to 0.0 + //loc->humidity = 0.0; return 0; } diff --git a/src/refract.c b/src/refract.c index 11a71e61..3b40cc16 100644 --- a/src/refract.c +++ b/src/refract.c @@ -176,6 +176,12 @@ double novas_radio_refraction(double jd_tt, const on_surface *loc, enum novas_re return NAN; } + + if(loc->humidity < -1.0 || loc->humidity > 101.0) { + novas_set_errno(EINVAL, fn, "invalid humidity value: %g", loc->humidity); + return NAN; + } + if(type == NOVAS_REFRACT_OBSERVED) return novas_inv_refract(novas_radio_refraction, jd_tt, loc, NOVAS_REFRACT_ASTROMETRIC, el); diff --git a/test/src/test-errors.c b/test/src/test-errors.c index 98815fca..1f21dfa5 100644 --- a/test/src/test-errors.c +++ b/test/src/test-errors.c @@ -1149,6 +1149,12 @@ static int test_refraction() { novas_optical_refraction(NOVAS_JD_J2000, NULL, NOVAS_REFRACT_OBSERVED, 10.0); novas_debug(0); + obs.humidity = -1.01; + if(check_nan("radio_refraction:humidity:lo", novas_radio_refraction(NOVAS_JD_J2000, &obs, NOVAS_REFRACT_OBSERVED, 10.0))) n++; + + obs.humidity = 101.01; + if(check_nan("radio_refraction:humidity:hi", novas_radio_refraction(NOVAS_JD_J2000, &obs, NOVAS_REFRACT_OBSERVED, 10.0))) n++; + return n; }