commit 139f83d5c296b191100cd199b553f03636273539
parent e61eb3a158492092793a2d0734da0cf707ae2d65
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Sun, 20 Mar 2016 16:25:15 +0100
Check the range of the parsed YAML values
Diffstat:
4 files changed, 85 insertions(+), 33 deletions(-)
diff --git a/src/schiff_args.c b/src/schiff_args.c
@@ -189,10 +189,15 @@ log_err
}
static res_T
-parse_yaml_double(const char* filename, const yaml_node_t* node, double* value)
+parse_yaml_double
+ (const char* filename,
+ const yaml_node_t* node,
+ const double min_val, /* Minimum valid value */
+ const double max_val, /* Maximum valid value */
+ double* value)
{
res_T res = RES_OK;
- ASSERT(filename && node && value);
+ ASSERT(filename && node && value && min_val < max_val);
if(node->type != YAML_SCALAR_NODE) {
log_err(filename, node, "expecting a floating point number.\n");
@@ -204,15 +209,26 @@ parse_yaml_double(const char* filename, const yaml_node_t* node, double* value)
node->data.scalar.value);
return RES_BAD_ARG;
}
-
+ if(*value < min_val || *value > max_val) {
+ log_err(filename, node,
+ "the floating point number %g is not in [%g, %g].\n",
+ *value, min_val, max_val);
+ return RES_BAD_ARG;
+ }
return RES_OK;
}
static res_T
-parse_yaml_uint(const char* filename, const yaml_node_t* node, unsigned* value)
+parse_yaml_uint
+ (const char* filename,
+ const yaml_node_t* node,
+ const unsigned min_val, /* Minimum valid value */
+ const unsigned max_val, /* Maximum valid value */
+ unsigned* value)
{
res_T res = RES_OK;
ASSERT(filename && node && value);
+ ASSERT(min_val < max_val);
if(node->type != YAML_SCALAR_NODE) {
log_err(filename, node, "expecting an unsigned integer.\n");
@@ -224,6 +240,12 @@ parse_yaml_uint(const char* filename, const yaml_node_t* node, unsigned* value)
node->data.scalar.value);
return RES_BAD_ARG;
}
+ if(*value < min_val || *value > max_val) {
+ log_err(filename, node,
+ "the unsigned integer %u is not in [%u, %u].\n",
+ *value, min_val, max_val);
+ return RES_BAD_ARG;
+ }
return RES_OK;
}
@@ -233,6 +255,8 @@ parse_yaml_param_lognormal
(const char* filename,
yaml_document_t* doc,
const yaml_node_t* lognormal,
+ const double min_val, /* Minimum valid value fo the parameter */
+ const double max_val, /* Maximum valid value of the parameter */
struct schiff_param* param)
{
enum {
@@ -243,7 +267,7 @@ parse_yaml_param_lognormal
size_t i;
int mask = 0; /* Register the parsed lognormal attributes */
res_T res = RES_OK;
- ASSERT(filename && doc && lognormal && param);
+ ASSERT(filename && doc && lognormal && param && min_val < max_val);
if(lognormal->type != YAML_MAPPING_NODE) {
log_err(filename, lognormal,
@@ -271,7 +295,8 @@ parse_yaml_param_lognormal
return RES_BAD_ARG;
}
mask |= ZETA;
- res = parse_yaml_double(filename, val, ¶m->data.lognormal.zeta);
+ res = parse_yaml_double /* mean value */
+ (filename, val, min_val, max_val, ¶m->data.lognormal.zeta);
/* lognormal sigma attribute */
} else if(!strcmp((char*)key->data.scalar.value, "sigma")) {
@@ -281,7 +306,8 @@ parse_yaml_param_lognormal
return RES_BAD_ARG;
}
mask |= SIGMA;
- res = parse_yaml_double(filename, val, ¶m->data.lognormal.sigma);
+ res = parse_yaml_double
+ (filename, val, DBL_MIN, DBL_MAX, ¶m->data.lognormal.sigma);
/* unknown attribute */
} else {
@@ -309,6 +335,8 @@ parse_yaml_param_histogram
(const char* filename,
yaml_document_t* doc,
const yaml_node_t* histo,
+ const double min_val, /* Minimum valid value fo the parameter */
+ const double max_val, /* Maximum valid value of the parameter */
struct schiff_param* param)
{
enum {
@@ -321,7 +349,7 @@ parse_yaml_param_histogram
int mask = 0; /* Register the parsed histogram attributes */
double accum_proba;
res_T res = RES_OK;
- ASSERT(filename && doc && histo && param);
+ ASSERT(filename && doc && histo && param && min_val < max_val);
param->distribution = SCHIFF_PARAM_HISTOGRAM;
param->data.histogram.entries = NULL;
@@ -351,7 +379,8 @@ parse_yaml_param_histogram
goto error;
}
mask |= LOWER;
- res = parse_yaml_double(filename, val, ¶m->data.histogram.lower);
+ res = parse_yaml_double
+ (filename, val, min_val, max_val, ¶m->data.histogram.lower);
if(res != RES_OK) goto error;
/* Histogram upper bound */
@@ -363,7 +392,8 @@ parse_yaml_param_histogram
goto error;
}
mask |= UPPER;
- res = parse_yaml_double(filename, val, ¶m->data.histogram.upper);
+ res = parse_yaml_double
+ (filename, val, min_val, max_val, ¶m->data.histogram.upper);
if(res != RES_OK) goto error;
/* Histogram entries */
@@ -399,7 +429,7 @@ parse_yaml_param_histogram
yaml_node_t* node;
node = yaml_document_get_node(doc, val->data.sequence.items.start[ientry]);
- res = parse_yaml_double(filename, node, &proba);
+ res = parse_yaml_double(filename, node, DBL_MIN, DBL_MAX, &proba);
if(res != RES_OK) goto error;
accum_proba += proba;
@@ -456,14 +486,17 @@ parse_yaml_param_distribution
(const char* filename,
yaml_document_t* doc,
const yaml_node_t* node,
+ const double min_val, /* Minimum valid value fo the parameter */
+ const double max_val, /* Maximum valid value of the parameter */
struct schiff_param* param)
{
res_T res = RES_OK;
- ASSERT(filename && doc && node && param);
+ ASSERT(filename && doc && node && param && min_val < max_val);
if(node->type == YAML_SCALAR_NODE) { /* Floating point constant */
param->distribution = SCHIFF_PARAM_CONSTANT;
- res = parse_yaml_double(filename, node, ¶m->data.constant);
+ res = parse_yaml_double
+ (filename, node, min_val, max_val, ¶m->data.constant);
if(res != RES_OK) return res;
} else if(node->type == YAML_MAPPING_NODE) {
@@ -480,10 +513,12 @@ parse_yaml_param_distribution
ASSERT(key->type == YAML_SCALAR_NODE);
if(!strcmp((char*)key->data.scalar.value, "lognormal")) {
- res = parse_yaml_param_lognormal(filename, doc, val, param);
+ res = parse_yaml_param_lognormal
+ (filename, doc, val, min_val, max_val, param);
if(res != RES_OK) return res;
} else if(!strcmp((char*)key->data.scalar.value, "histogram")) {
- res = parse_yaml_param_histogram(filename, doc, val, param);
+ res = parse_yaml_param_histogram
+ (filename, doc, val, min_val, max_val, param);
if(res != RES_OK) return res;
} else {
log_err(filename, key, "unknown parameter distribution `%s'.\n",
@@ -542,7 +577,7 @@ parse_yaml_ellipsoid
return RES_BAD_ARG;
}
mask |= PROBA;
- res = parse_yaml_double(filename, val, geom_proba);
+ res = parse_yaml_double(filename, val, DBL_MIN, DBL_MAX, geom_proba);
/* # slices used to discretized the triangular ellipsoid */
} else if(!strcmp((char*)key->data.scalar.value, "slices")) {
@@ -552,7 +587,8 @@ parse_yaml_ellipsoid
return RES_BAD_ARG;
}
mask |= SLICES;
- res = parse_yaml_uint(filename, val, &geom->data.ellipsoid.nslices);
+ res = parse_yaml_uint
+ (filename, val, 4, 32768, &geom->data.ellipsoid.nslices);
}
/* Length of the ellipsoid semi-principal axis */
@@ -564,7 +600,7 @@ parse_yaml_ellipsoid
} \
mask |= LENGTH_ ## Axis; \
res = parse_yaml_param_distribution \
- (filename, doc, val, &geom->data.ellipsoid.Axis); \
+ (filename, doc, val, DBL_MIN, DBL_MAX, &geom->data.ellipsoid.Axis); \
} (void)0
else if(!strcmp((char*)key->data.scalar.value, "a")) {
PARSE_SEMI_PRINCIPAL_AXIS(a);
@@ -650,7 +686,7 @@ parse_yaml_cylinder
return RES_BAD_ARG;
}
mask |= PROBA;
- res = parse_yaml_double(filename, val, geom_proba);
+ res = parse_yaml_double(filename, val, DBL_MIN, DBL_MAX, geom_proba);
/* Cylinder radius */
} else if(!strcmp((char*)key->data.scalar.value, "radius")) {
@@ -660,7 +696,7 @@ parse_yaml_cylinder
}
mask |= RADIUS;
res = parse_yaml_param_distribution
- (filename, doc, val, &geom->data.cylinder.radius);
+ (filename, doc, val, DBL_MIN, DBL_MAX, &geom->data.cylinder.radius);
/* Cylinder height */
} else if(!strcmp((char*)key->data.scalar.value, "height")) {
@@ -670,7 +706,7 @@ parse_yaml_cylinder
}
mask |= HEIGHT;
res = parse_yaml_param_distribution
- (filename, doc, val, &geom->data.cylinder.height);
+ (filename, doc, val, DBL_MIN, DBL_MAX, &geom->data.cylinder.height);
/* Cylinder aspect ratio */
} else if(!strcmp((char*)key->data.scalar.value, "aspect_ratio")) {
@@ -680,7 +716,7 @@ parse_yaml_cylinder
}
mask |= ASPECT_RATIO;
res = parse_yaml_double
- (filename, val, &geom->data.cylinder.aspect_ratio);
+ (filename, val, DBL_MIN, DBL_MAX, &geom->data.cylinder.aspect_ratio);
/* # slices used to discretized the triangular cylinder */
} else if(!strcmp((char*)key->data.scalar.value, "slices")) {
@@ -690,7 +726,8 @@ parse_yaml_cylinder
return RES_BAD_ARG;
}
mask |= SLICES;
- res = parse_yaml_uint(filename, val, &geom->data.cylinder.nslices);
+ res = parse_yaml_uint
+ (filename, val, 4, 32768, &geom->data.cylinder.nslices);
/* Error */
} else {
@@ -773,7 +810,7 @@ parse_yaml_sphere
return RES_BAD_ARG;
}
mask |= PROBA;
- res = parse_yaml_double(filename, val, geom_proba);
+ res = parse_yaml_double(filename, val, DBL_MIN, DBL_MAX, geom_proba);
/* Sphere radius */
} else if(!strcmp((char*)key->data.scalar.value, "radius")) {
@@ -783,7 +820,7 @@ parse_yaml_sphere
}
mask |= RADIUS;
res = parse_yaml_param_distribution
- (filename, doc, val, &geom->data.sphere.radius);
+ (filename, doc, val, DBL_MIN, DBL_MAX, &geom->data.sphere.radius);
/* # slices used to discretized the triangular sphere */
} else if(!strcmp((char*)key->data.scalar.value, "slices")) {
@@ -793,7 +830,8 @@ parse_yaml_sphere
return RES_BAD_ARG;
}
mask |= SLICES;
- res = parse_yaml_uint(filename, val, &geom->data.sphere.nslices);
+ res = parse_yaml_uint
+ (filename, val, 4, 32768, &geom->data.sphere.nslices);
/* Error */
} else {
diff --git a/src/schiff_geometry.c b/src/schiff_geometry.c
@@ -467,13 +467,18 @@ schiff_geometry_distribution_release
struct geometry_distribution_context* ctx;
size_t i, count;
ASSERT(distrib);
- ctx = distrib->context;
+ if(!distrib->context) return;
- count = sa_size(ctx->meshes);
- FOR_EACH(i, 0, count) schiff_mesh_release(&ctx->meshes[i]);
- sa_release(ctx->meshes);
- sa_release(ctx->geometries);
- SSP(ran_discrete_ref_put(ctx->ran_geometries));
+ ctx = distrib->context;
+ if(ctx->meshes) {
+ count = sa_size(ctx->meshes);
+ FOR_EACH(i, 0, count) schiff_mesh_release(&ctx->meshes[i]);
+ sa_release(ctx->meshes);
+ }
+ if(ctx->geometries)
+ sa_release(ctx->geometries);
+ if(ctx->ran_geometries)
+ SSP(ran_discrete_ref_put(ctx->ran_geometries));
mem_rm(ctx);
}
@@ -501,6 +506,8 @@ schiff_geometry_distribution_init
res = RES_MEM_ERR;
goto error;
}
+ /* Directly setyp the distribution context to avoid memory leaks on error */
+ distrib->context = ctx;
if(!sa_add(ctx->meshes, ngeoms)) {
fprintf(stderr,
@@ -508,6 +515,7 @@ schiff_geometry_distribution_init
res = RES_MEM_ERR;
goto error;
}
+ memset(ctx->meshes, 0, sizeof(ctx->meshes[0])*ngeoms);
if(!sa_add(ctx->geometries, ngeoms)) {
fprintf(stderr,
@@ -551,7 +559,6 @@ schiff_geometry_distribution_init
distrib->material.get_property = get_material_property;
distrib->material.material = properties;
- distrib->context = ctx;
distrib->sample = geometry_sample;
distrib->caracteristic_length = caracteristic_length;
diff --git a/src/schiff_mesh.c b/src/schiff_mesh.c
@@ -322,6 +322,9 @@ void
schiff_mesh_release(struct schiff_mesh* mesh)
{
ASSERT(mesh);
+ if(mesh->coordinates == SCHIFF_NO_COORDINATE)
+ return; /* No coordinate is setuped */
+
switch(mesh->coordinates) {
case SCHIFF_CARTESIAN:
darray_float_release(&mesh->vertices.cartesian);
@@ -334,5 +337,6 @@ schiff_mesh_release(struct schiff_mesh* mesh)
default: FATAL("Unreachable code\n"); break;
}
darray_uint_release(&mesh->indices);
+ mesh->coordinates = SCHIFF_NO_COORDINATE;
}
diff --git a/src/schiff_mesh.h b/src/schiff_mesh.h
@@ -39,6 +39,7 @@ struct sin_cos { double angle, sinus, cosine; };
#include <rsys/dynamic_array.h>
enum schiff_coordinates {
+ SCHIFF_NO_COORDINATE, /* No coordinate is setuped */
SCHIFF_POLAR,
SCHIFF_CARTESIAN
};
@@ -54,6 +55,8 @@ struct schiff_mesh {
/* Used only by polar coordinates */
struct darray_sincos thetas; /* List of thetas, cos(theta) , sin(theta) */
struct darray_sincos phis; /* List of phis, cos(phi), sin(phi) */
+
+ int is_init;
};
extern LOCAL_SYM res_T