commit 5198aca0d3ef99705016a34153bc316e228b0ddd
parent c9e619eaffa4a7a23c1153e43539ac589c3e1f83
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Tue, 10 Mar 2026 09:51:14 +0100
Check the number of isotopes in a molecule
Even though the list of isotopes is dynamic and can therefore be as long
as necessary, a molecule must not have more than SHTR_MAX_ISOTOPE_COUNT
isotopes. This constant is used to facilitate the management of a
molecule by allowing its memory space to be managed statically. It is
not only used internally (notably by the hash function), but also
exposed as an API constant, so that the caller can rely on it.
Hence this check during loading to ensure that the number of isotopes
per molecule does not exceed SHTR_MAX_ISOTOPE_COUNT.
A test is added to verify this new loading error.
Diffstat:
2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/src/shtr_isotope_metadata.c b/src/shtr_isotope_metadata.c
@@ -153,6 +153,7 @@ flush_molecule
struct molecule* molecule, /* Currently parsed molecule */
struct txtrdr* txtrdr)
{
+ size_t nisotopes = 0;
size_t ientry = SIZE_MAX;
size_t* pimolecule = NULL;
res_T res = RES_OK;
@@ -168,6 +169,17 @@ flush_molecule
str_cget(&molecule->name));
}
+ nisotopes = molecule->isotopes_range[1] - molecule->isotopes_range[0];
+ if(nisotopes >= SHTR_MAX_ISOTOPE_COUNT) {
+ ERROR(metadata->shtr,
+ "%s:%lu: %s has %lu isotopes, while the maximum number supported is %d.\n",
+ txtrdr_get_name(txtrdr), (unsigned long)txtrdr_get_line_num(txtrdr),
+ str_cget(&molecule->name), (unsigned long)nisotopes,
+ SHTR_MAX_ISOTOPE_COUNT);
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
/* Fetch the index where the molecule is going to be store */
ientry = darray_molecule_size_get(&metadata->molecules);
CHK(ientry < SHTR_MAX_MOLECULE_COUNT);
diff --git a/src/test_shtr_isotope_metadata.c b/src/test_shtr_isotope_metadata.c
@@ -455,9 +455,13 @@ test_serialization(struct shtr* shtr)
static void
test_load_failures(struct shtr* shtr)
{
+ struct shtr_isotope CO2_too_many_isotopes[SHTR_MAX_ISOTOPE_COUNT+1] = {0};
+ struct shtr_molecule CO2_bad = SHTR_MOLECULE_NULL;
+
struct shtr_isotope isotope = SHTR_ISOTOPE_NULL;
struct shtr_isotope_metadata* mdata = NULL;
FILE* fp = NULL;
+ size_t i = 0;
CHK(shtr);
@@ -534,6 +538,21 @@ test_load_failures(struct shtr* shtr)
rewind(fp);
CHK(shtr_isotope_metadata_load_stream(shtr, fp, NULL, &mdata) == RES_BAD_ARG);
CHK(fclose(fp) == 0);
+
+ /* Too many isotope for a molecule */
+ FOR_EACH(i, 0, SHTR_MAX_ISOTOPE_COUNT+1) {
+ CO2_too_many_isotopes[i] = CO2_isotopes[i % CO2.nisotopes];
+ CO2_too_many_isotopes[i].abundance = 1.0/(double)(SHTR_MAX_ISOTOPE_COUNT+1);
+ }
+ CHK(fp = tmpfile());
+ CO2_bad = CO2;
+ CO2_bad.nisotopes = SHTR_MAX_ISOTOPE_COUNT+1;
+ CO2_bad.isotopes = CO2_too_many_isotopes;
+ fprintf(fp, "Molecule # Iso Abundance Q(296K) gj Molar Mass(g)\n");
+ molecule_print(fp, &CO2_bad);
+ rewind(fp);
+ CHK(shtr_isotope_metadata_load_stream(shtr, fp, NULL, &mdata) == RES_MEM_ERR);
+ CHK(fclose(fp) == 0);
}
static void