From fa502afcbe7034b7f63a4d6e6936d4d9c8298cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Sz=C3=A1sz?= Date: Mon, 25 Nov 2024 14:15:35 +0100 Subject: [PATCH 1/4] Fix ROBOSPECT to compile with GSL 2.x GSL 2.0 broke backward compatibility with GSL 1.x code, which prevented ROBOSPECT from being used with modern Linux distributions. The fix was relatively easy. The only relevant difference that affected the ROBOSPECT code was the need to calculate the Jacobian matrix explicitly via the gsl_mulitifit_fdfsolver_jac() function. --- doc/QUICKSTART | 2 +- src/gsllm-multigauss.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/QUICKSTART b/doc/QUICKSTART index 89585d1..d51b710 100644 --- a/doc/QUICKSTART +++ b/doc/QUICKSTART @@ -7,7 +7,7 @@ INSTALLATION The following libraries are used by ROBOSPECT: - * libgsl : required. Tested to work with versions > v1.9. + * libgsl : required. Tested to work with versions > v2.0. * libcfitsio : optional requirement to allow FITS image input. * libplplotd : optional requirement to produce line fit plots. diff --git a/src/gsllm-multigauss.c b/src/gsllm-multigauss.c index f7fe119..3013b2a 100644 --- a/src/gsllm-multigauss.c +++ b/src/gsllm-multigauss.c @@ -177,7 +177,9 @@ int lm_multigauss(double *X, double *Y, double *E, int N, data.iteration++; status = gsl_multifit_fdfsolver_iterate(S); status = gsl_multifit_test_delta(S->dx,S->x,1e-35,1e-35); - gsl_multifit_covar(S->J,0.0,covar); + gsl_matrix *J = gsl_matrix_alloc(f.n, f.p); + gsl_multifit_fdfsolver_jac(S, J); + gsl_multifit_covar(J, 0.0, covar); for (j = 0; j < M; j++) { fprintf(stderr,"mml: (%d/%d) %d %f %f (%f,%f,%f) +- (%f,%f,%f)\n", j,M,data.iteration,-1.0,0.0,data.m[j],data.s[j],data.A[j],data.dm[j],data.ds[j],data.dA[j]); From 51120db4e5a6adec5d012725e5f04bb47390141c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Sz=C3=A1sz?= Date: Mon, 25 Nov 2024 18:22:38 +0100 Subject: [PATCH 2/4] Fix compiler warnings The compiler shows several warnings which should be addressed: fileio.c:5: Pointer to the local statically allocated char array cannot be returned from the function, because once the program leaves the scope of the function, there is no guarantee that the array will be preserved. Making the variable static is the easiest fix of this issue. fileio/input_fitsWCS.c:93: The k variable can contain a signed integer number (from -2147483646 to 2147483646) that will occupy between 3 and 11 bytes when formatted into a %03d string. Note that the %03d format specifies the *minimum* number of digits, but it does not prevent from including number greater than 999. The snprintf() function then does the truncation, and thus prevents buffer overflow, but this is generally quite a bad practice. In this scenario the -Wformat-truncation compiler argument generates the warning if a developer does not at least check if the return value of snprintf() is not negative. fileio/input_fitsWCS:97: This is one of the most dangerous pieces of code within the ROBOSPECT that is most likely responsible for unpredictable behavior. The sprintf() function simply cannot read and write into the same string at the same time. Furthermore, space (' ') as a flag of the format string do not have any function in "%s" format and it is simply ignored by sprintf(). I have rewritten this code using pointer arithmetic to avoid frequent NULL pointer checking. models/continuum_blackbody.c:76: The undeclared chi variable contains a random value during the first log_comment() call. Although it is not critical, accessing undeclared variable should be avoided in any circumstances. The iterations starts with chi square value 99e99 and this is exactly what we should be printed during the first log_comment() call. --- src/fileio.c | 2 +- src/fileio/input_fitsWCS.c | 14 +++++++++----- src/models/continuum_blackbody.c | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/fileio.c b/src/fileio.c index 936d10b..24741f6 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -2,7 +2,7 @@ #include "robo.h" char *generate_filename(opts *options, char *rule) { - char root[1024]; + static char root[1024]; char order[16]; if ((options->max_order != 0)&&(strcasecmp(rule,"LOG") != 0)) { snprintf(order,sizeof(order),"_order%03d",options->order); diff --git a/src/fileio/input_fitsWCS.c b/src/fileio/input_fitsWCS.c index e9e4277..4734fed 100644 --- a/src/fileio/input_fitsWCS.c +++ b/src/fileio/input_fitsWCS.c @@ -24,7 +24,8 @@ fits_WCS *read_fits_WCS(fitsfile *ff) { char keyword[9]; char *fullspect; char *token; - int k; + int k, pos; + int ret; fits_read_keyword(ff,"WAT0_001",value,comment,&status); FRE; if ((strcasecmp(value,"'system=world'") == 0)||(status != 0)) { @@ -89,12 +90,15 @@ fits_WCS *read_fits_WCS(fitsfile *ff) { status = 0; fullspect = malloc(WCS->N * 2 * 80); - for (k = 1; k < WCS->N * 2; k++) { - snprintf(keyword,sizeof(keyword),"WAT2_%03d",k); + for (k = 1, pos = 0; k < WCS->N * 2; k++) { + ret = snprintf(keyword, sizeof(keyword), "WAT2_%03d", k); + if (ret < 0) { + fprintf(stderr, "robospect: %s: %d: Buffer overflow\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } fits_read_key(ff,TSTRING,keyword,value,NULL,&status); if (status == 0) { - /* This right here? This is fucking ridiculous. */ - sprintf(fullspect,"%s%- 68s",fullspect,value); + pos += sprintf(&fullspect[pos], "%-68s", value); } else { k = WCS->N * 3; diff --git a/src/models/continuum_blackbody.c b/src/models/continuum_blackbody.c index b5a7d0d..c7cf8c6 100644 --- a/src/models/continuum_blackbody.c +++ b/src/models/continuum_blackbody.c @@ -77,7 +77,7 @@ void generate_model_continuum_blackbody(opts *options, data *D, model *M) { "gmcbb: (%d/%d) %g (%g %g %g) (PREFIT)", i,D->N, tau * HCKB,s,A,eta, - chi,iterations + 99e99,iterations ); iterations = multifunction(D->x,D->y,EE,D->N, From e961b723acf91b1c7600082b64a68fb654d16660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Sz=C3=A1sz?= Date: Mon, 25 Nov 2024 19:08:26 +0100 Subject: [PATCH 3/4] Fix missing memory allocation error handling The return value of the malloc() and realloc() calls was never checked for an error. Although this did not produce any warning, it is generally a very bad practice. My implementation of the memory allocation error handling might be simplistic, but it represents the bare minimum that should have been implemented a long ago. --- src/config.c | 12 ++ src/fileio/input_data.c | 44 ++++++++ src/fileio/input_fitsWCS.c | 16 +++ src/fileio/input_lines.c | 156 ++++++++++++++++++++++++++ src/fileio/output_logs.c | 4 + src/fileio/output_plots.c | 20 ++++ src/gsllm-multigauss.c | 4 + src/linefinder.c | 9 ++ src/math.c | 42 ++++++- src/math/nlls-multifunction.c | 64 +++++++++++ src/model.c | 40 +++++++ src/models/continuum_blackbody.c | 4 + src/models/continuum_boxcar.c | 4 + src/models/continuum_devel.c | 20 ++++ src/models/continuum_fft.c | 4 + src/models/continuum_histogram.c | 4 + src/models/continuum_logboxcar.c | 4 + src/models/continuum_peak_boxcar.c | 4 + src/models/continuum_robust_linear.c | 12 ++ src/models/deblend_nlls.c | 36 ++++++ src/models/line_isolated_gaussian.c | 4 + src/models/line_nonparametric.c | 8 ++ src/models/line_pre.c | 8 ++ src/models/line_threestage_gaussian.c | 48 ++++++++ src/nlls-gaussfit.c | 28 +++++ src/nlls-multigauss.c | 40 +++++++ src/noise.c | 4 + src/rv.c | 28 +++++ src/vectors.c | 28 +++++ 29 files changed, 698 insertions(+), 1 deletion(-) diff --git a/src/config.c b/src/config.c index c149853..527ccb0 100644 --- a/src/config.c +++ b/src/config.c @@ -8,6 +8,10 @@ /* Set up a default option structure. */ opts *alloc_options() { opts *O = malloc(sizeof(opts)); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } O->psf_width = 5.0; /* to remove */ O->continuum_box = 40.0; @@ -357,6 +361,10 @@ void usage_block(opts *O) { char * get_time() { time_t curtime = time(NULL); char *output = malloc(32 * sizeof(char)); + if (output == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } strftime(output,32,DATE_FORMAT,localtime(&curtime)); return(output); } @@ -565,6 +573,10 @@ void set_options(opts *O, int argc, char *argv[]) { /* Load input file or read from stdin */ if (argv[optind] == NULL) { O->infilename = malloc(32 * sizeof(char)); + if (O->infilename == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(O->infilename,32,"/dev/stdin"); } else { diff --git a/src/fileio/input_data.c b/src/fileio/input_data.c index e6bfbdd..5c00456 100644 --- a/src/fileio/input_data.c +++ b/src/fileio/input_data.c @@ -3,20 +3,56 @@ data *alloc_data(int size) { data *D = malloc(sizeof(data)); + if (D == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } D->N = size; D->x = malloc(size * sizeof(double)); + if (D->x == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } D->y = malloc(size * sizeof(double)); + if (D->y == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } D->e = malloc(size * sizeof(double)); + if (D->e == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } D->yO= malloc(size * sizeof(double)); + if (D->yO == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } return(D); } void realloc_data(data *D, int size) { D->N = size; D->x = realloc(D->x,size * sizeof(double)); + if (D->x == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } D->y = realloc(D->y,size * sizeof(double)); + if (D->y == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } D->e = realloc(D->e,size * sizeof(double)); + if (D->e == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } D->yO= realloc(D->yO,size * sizeof(double)); + if (D->yO == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } } void free_data(data *D) { @@ -189,12 +225,20 @@ data *read_data_fits(opts *options, int *N) { fits_get_img_size(ff,naxis,lpixel,&status); FRE; if (naxis == 1) { image = malloc(lpixel[0] * sizeof(double)); + if (image == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } fits_read_pix(ff,TDOUBLE,fpixel,lpixel[0],NULL,image,&naxis,&status); FRE; lpixel[1] = 1; } else if (naxis == 2) { fpixel[1] = options->order + 1; /* This probably should be correctly handled by a DISP-AXIS header. */ image = malloc(lpixel[0] * sizeof(double)); + if (image == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } fits_read_pix(ff,TDOUBLE,fpixel,lpixel[0] ,NULL,image,&naxis,&status); FRE; if (options->max_order == 0) { options->max_order = lpixel[1] - 1; diff --git a/src/fileio/input_fitsWCS.c b/src/fileio/input_fitsWCS.c index 4734fed..878f00f 100644 --- a/src/fileio/input_fitsWCS.c +++ b/src/fileio/input_fitsWCS.c @@ -10,6 +10,10 @@ typedef enum { fits_WCS *read_fits_WCS(fitsfile *ff) { fits_WCS *WCS = malloc(sizeof(fits_WCS)); + if (WCS == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; char value[80]; @@ -55,7 +59,15 @@ fits_WCS *read_fits_WCS(fitsfile *ff) { } WCS->N = atoi(value); WCS->x0 = malloc(WCS->N * sizeof(double)); + if (WCS->x0 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } WCS->xd = malloc(WCS->N * sizeof(double)); + if (WCS->xd == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } fits_read_keyword(ff,"WAT1_001",value,NULL,&status); FRE; @@ -89,6 +101,10 @@ fits_WCS *read_fits_WCS(fitsfile *ff) { else if (S == SPECT_MULTISPEC) { status = 0; fullspect = malloc(WCS->N * 2 * 80); + if (fullspect == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (k = 1, pos = 0; k < WCS->N * 2; k++) { ret = snprintf(keyword, sizeof(keyword), "WAT2_%03d", k); diff --git a/src/fileio/input_lines.c b/src/fileio/input_lines.c index 1d86775..205f985 100644 --- a/src/fileio/input_lines.c +++ b/src/fileio/input_lines.c @@ -3,30 +3,106 @@ lines *alloc_lines(int size) { lines *L = malloc(sizeof(lines)); + if (L == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->l = size; L->b = 1; L->m = malloc(size * sizeof(double)); + if (L->m == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->s = malloc(size * sizeof(double)); + if (L->s == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->F = malloc(size * sizeof(double)); + if (L->F == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->eta = malloc(size * sizeof(double)); + if (L->eta == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->dm = malloc(size * sizeof(double)); + if (L->dm == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->ds = malloc(size * sizeof(double)); + if (L->ds == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->dF = malloc(size * sizeof(double)); + if (L->dF == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->deta = malloc(size * sizeof(double)); + if (L->deta == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->mp = malloc(size * sizeof(double)); + if (L->mp == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->sp = malloc(size * sizeof(double)); + if (L->sp == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->Fp = malloc(size * sizeof(double)); + if (L->Fp == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->etap = malloc(size * sizeof(double)); + if (L->etap == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->x0 = malloc(size * sizeof(double)); + if (L->x0 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->chi = malloc(size * sizeof(double)); + if (L->chi == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->comment = malloc(size * sizeof(char **)); + if (L->comment == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->manual = malloc(size * sizeof(int)); + if (L->manual == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->flags = malloc(size * sizeof(int)); + if (L->flags == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->blend_group = malloc(size * sizeof(int)); + if (L->blend_group == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->x0[0] = 0.0; return(L); } @@ -34,24 +110,96 @@ lines *alloc_lines(int size) { void realloc_lines(lines *L, int size) { L->l = size; L->x0 = realloc(L->x0,size * sizeof(double)); + if (L->x0 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->chi = realloc(L->chi,size * sizeof(double)); + if (L->chi == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->m = realloc(L->m,size * sizeof(double)); + if (L->m == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->s = realloc(L->s,size * sizeof(double)); + if (L->s == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->F = realloc(L->F,size * sizeof(double)); + if (L->F == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->eta = realloc(L->eta,size * sizeof(double)); + if (L->eta == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->dm = realloc(L->dm,size * sizeof(double)); + if (L->dm == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->ds = realloc(L->ds,size * sizeof(double)); + if (L->ds == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->dF = realloc(L->dF,size * sizeof(double)); + if (L->dF == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->deta = realloc(L->deta,size * sizeof(double)); + if (L->deta == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->mp = realloc(L->mp,size * sizeof(double)); + if (L->mp == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->sp = realloc(L->sp,size * sizeof(double)); + if (L->sp == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->Fp = realloc(L->Fp,size * sizeof(double)); + if (L->Fp == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->etap = realloc(L->etap,size * sizeof(double)); + if (L->etap == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->comment = realloc(L->comment,size * sizeof(char **)); + if (L->comment == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->manual = realloc(L->manual, size * sizeof(int)); + if (L->manual == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->flags = realloc(L->flags, size * sizeof(int)); + if (L->flags == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } L->blend_group = realloc(L->blend_group, size * sizeof(int)); + if (L->blend_group == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } } void free_lines(lines *L) { @@ -301,7 +449,15 @@ void validate_line_peaks(opts *options, data *D, model *M) { log_comment(options,ROBO_VERBOSE_DEBUG,"validating peaks"); /* Scan for lines that may be offset */ x = malloc(M->L->l * sizeof(double)); + if (x == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } dw = malloc(M->L->l * sizeof(double)); + if (dw == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (i = 0; i < M->L->l; i++) { /* Find the current peak bin. */ for (j = j_peak; D->x[j] < M->L->x0[i]; j++) { diff --git a/src/fileio/output_logs.c b/src/fileio/output_logs.c index ffbb8df..0e317e3 100644 --- a/src/fileio/output_logs.c +++ b/src/fileio/output_logs.c @@ -11,6 +11,10 @@ void log_comment(opts *options, int level, char *format, ...) { if (options->verbose & level) { comment = malloc(sizeof(char) * LOG_COMMENT_LENGTH); + if (comment == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } va_start(arg,format); status = vsnprintf(comment,LOG_COMMENT_LENGTH,format,arg); if (status > LOG_COMMENT_LENGTH) { diff --git a/src/fileio/output_plots.c b/src/fileio/output_plots.c index 28b9f48..ec6780d 100644 --- a/src/fileio/output_plots.c +++ b/src/fileio/output_plots.c @@ -213,10 +213,30 @@ void render_line_plots(opts *options, data *D, model *M) { } } x = malloc(sizeof(double) * Nsamples); + if (x == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } data = malloc(sizeof(double) * Nsamples); + if (data == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } model = malloc(sizeof(double) * Nsamples); + if (model == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } alt_model = malloc(sizeof(double) * Nsamples); + if (alt_model == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } continuum = malloc(sizeof(double) * Nsamples); + if (continuum == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (j = 0; j < Nsamples; j++) { x[j] = D->x[j + Noffset]; data[j] = D->yO[j + Noffset]; diff --git a/src/gsllm-multigauss.c b/src/gsllm-multigauss.c index 3013b2a..dc7214e 100644 --- a/src/gsllm-multigauss.c +++ b/src/gsllm-multigauss.c @@ -131,6 +131,10 @@ int lm_multigauss(double *X, double *Y, double *E, int N, int i,j; x_init = malloc(3 * M * sizeof(double)); + if (x_init == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } data.m = m; data.s = s; diff --git a/src/linefinder.c b/src/linefinder.c index d71c63e..464142f 100644 --- a/src/linefinder.c +++ b/src/linefinder.c @@ -55,6 +55,10 @@ lines *linefinder_naive(opts *options, data *D, model *M) { L->eta[j] = 0.0; L->manual[j] = 0; L->comment[j] = malloc(sizeof(char) * AUTO_COMMENT_LENGTH); + if (L->comment[j] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(L->comment[j],AUTO_COMMENT_LENGTH,AUTO_COMMENT_FORMAT,AUTO_COMMENT_VALUES); L->flags[j] = ROBO_INIT; L->blend_group[j] = 0; @@ -140,6 +144,11 @@ lines *linefinder_with_prior(opts *options, data *D, model *M) { L->eta[j] = 0.0; L->manual[j] = 0; L->comment[j] = malloc(sizeof(char) * AUTO_COMMENT_LENGTH); + if (L->comment[j] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } + snprintf(L->comment[j],AUTO_COMMENT_LENGTH,AUTO_COMMENT_FORMAT,AUTO_COMMENT_VALUES); L->flags[j] = ROBO_INIT; L->blend_group[j] = 0; diff --git a/src/math.c b/src/math.c index 5e11e5a..56b4490 100644 --- a/src/math.c +++ b/src/math.c @@ -62,6 +62,10 @@ int comp (const void *a, const void *b) { stats *array_stats_safe(double *x, int N) { int i; stats *S = malloc(sizeof(stats)); + if (S == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } S->N = N; S->mean = 0; @@ -93,7 +97,15 @@ stats *array_stats_safe(double *x, int N) { stats *array_stats(double *x, int N) { int i; stats *S = malloc(sizeof(stats)); + if (S == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double *MADarr = malloc(sizeof(double) * N); + if (MADarr == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } S->N = N; S->mean = 0; S->sigma = 0; @@ -131,9 +143,25 @@ stats *histogram_and_gaussfit(double *x, int N) { int i,j; int M = (int) sqrt(N); stats *S = malloc(sizeof(stats)); + if (S == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double *X = malloc(sizeof(double) * M); + if (X == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double *Y = malloc(sizeof(double) * M); + if (Y == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double *E = malloc(sizeof(double) * M); + if (E == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double F,dm,ds,dA,chi; S->N = N; S->mean = 0; @@ -210,6 +238,10 @@ double equivalent_width_error(lines *L, int i) { double *make_psf(double s, int N) { double *v = malloc(N * sizeof(double)); + if (v == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; for (i = 0; i < N; i++) { @@ -235,8 +267,16 @@ void robust_linear_fit (double *x, double *y, int N, double *m, double *b, doubl double S,Sx,Sy,Sxx,Syy,Sxy,D; int iterations = 0; - /* double *e = malloc(sizeof(double) * N); */ + /* double *e = malloc(sizeof(double) * N); */ + /* if (e == NULL) { */ + /* fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); */ + /* exit(EXIT_FAILURE); */ + /* } */ double *w = malloc(sizeof(double) * N); + if (w == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; for (i = 0; i < N; i++) { diff --git a/src/math/nlls-multifunction.c b/src/math/nlls-multifunction.c index 829ba02..85e9534 100644 --- a/src/math/nlls-multifunction.c +++ b/src/math/nlls-multifunction.c @@ -198,9 +198,25 @@ int multifunction(double *X, double *Y, double *E, int N, /* Save initial values in case we need to reset. */ mi = malloc(sizeof(double) * M); + if (mi == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } si = malloc(sizeof(double) * M); + if (si == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } Ai = malloc(sizeof(double) * M); + if (Ai == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } etai = malloc(sizeof(double) * M); + if (etai == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (j = 0; j < M; j++) { mi[j] = m[j]; si[j] = s[j]; @@ -211,14 +227,46 @@ int multifunction(double *X, double *Y, double *E, int N, /* Prepare test values */ m1 = malloc(sizeof(double) * M); + if (m1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } s1 = malloc(sizeof(double) * M); + if (s1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } A1 = malloc(sizeof(double) * M); + if (A1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } eta1 = malloc(sizeof(double) * M); + if (eta1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } m2 = malloc(sizeof(double) * M); + if (m2 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } s2 = malloc(sizeof(double) * M); + if (s2 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } A2 = malloc(sizeof(double) * M); + if (A2 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } eta2 = malloc(sizeof(double) * M); + if (eta2 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } /* Iterate until either the fractional proposed update is smaller than */ /* the tolerance, or we reach 1000 iterations (which suggests no fit). */ @@ -597,9 +645,25 @@ int multifunction(double *X, double *Y, double *E, int N, /* Save initial values in case we need to reset. */ mi = malloc(sizeof(double) * M); + if (mi == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } si = malloc(sizeof(double) * M); + if (si == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } Ai = malloc(sizeof(double) * M); + if (Ai == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } etai = malloc(sizeof(double) * M); + if (etai == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (j = 0; j < M; j++) { mi[j] = m[j]; si[j] = s[j]; diff --git a/src/model.c b/src/model.c index 2ec8607..5dc4e67 100644 --- a/src/model.c +++ b/src/model.c @@ -12,12 +12,32 @@ model *alloc_models(opts *options, data *D) { int i; model *M = malloc(sizeof(model)); + if (M == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } M->N = D->N; M->x = malloc(M->N * sizeof(double)); + if (M->x == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } M->continuum = malloc(M->N * sizeof(double)); + if (M->continuum == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } M->lines = malloc(M->N * sizeof(double)); + if (M->lines == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } M->alternate = malloc(M->N * sizeof(double)); + if (M->alternate == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (i = 0; i < D->N; i++) { M->x[i] = D->x[i]; @@ -26,22 +46,42 @@ model *alloc_models(opts *options, data *D) { } if (!options->continuum_model_name) { options->continuum_model_name = malloc(NAMESIZE * sizeof(char)); + if (options->continuum_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(options->continuum_model_name,NAMESIZE,"default"); } if (!options->line_model_name) { options->line_model_name = malloc(NAMESIZE * sizeof(char)); + if (options->line_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(options->line_model_name,NAMESIZE,"default"); } if (!options->noise_model_name) { options->noise_model_name = malloc(NAMESIZE * sizeof(char)); + if (options->noise_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(options->noise_model_name,NAMESIZE,"default"); } if (!options->deblend_model_name) { options->deblend_model_name = malloc(NAMESIZE * sizeof(char)); + if (options->deblend_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(options->deblend_model_name,NAMESIZE,"default"); } if (!options->function_model_name) { options->function_model_name = malloc(NAMESIZE * sizeof(char)); + if (options->function_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(options->function_model_name,NAMESIZE,"default"); } diff --git a/src/models/continuum_blackbody.c b/src/models/continuum_blackbody.c index c7cf8c6..0635655 100644 --- a/src/models/continuum_blackbody.c +++ b/src/models/continuum_blackbody.c @@ -20,6 +20,10 @@ void generate_model_continuum_blackbody(opts *options, data *D, model *M) { double A,tau,lT; double *EE = malloc(sizeof(double) * D->N); + if (EE == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double l0,l1; double f0,f1; double K; diff --git a/src/models/continuum_boxcar.c b/src/models/continuum_boxcar.c index 72102bf..791a1d8 100644 --- a/src/models/continuum_boxcar.c +++ b/src/models/continuum_boxcar.c @@ -5,6 +5,10 @@ void generate_model_continuum_boxcar(opts *options, data *D, model *M) { int i,j; stats *S1; double *v1 = malloc(sizeof(double) * D->N); + if (v1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int n1; for (i = 0; i < D->N; i += 1) { diff --git a/src/models/continuum_devel.c b/src/models/continuum_devel.c index 2e8a263..a0cb77f 100644 --- a/src/models/continuum_devel.c +++ b/src/models/continuum_devel.c @@ -16,6 +16,10 @@ void generate_model_continuum_devel(opts *options, data *D, model *M) { int i,j; stats *S1; double *v1 = malloc(sizeof(double) * D->N); + if (v1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int n1; for (i = 0; i < D->N; i += 1) { @@ -37,6 +41,10 @@ void generate_model_continuum_devel(opts *options, data *D, model *M) { S1 = array_stats(v1,n1); /* Create scratch array we can sort; */ double *v2 = malloc(sizeof(double) * n1); + if (v2 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (j = 0; j < n1; j++) { v2[j] = v1[j] - S1->med; } @@ -54,6 +62,10 @@ void generate_model_continuum_devel(opts *options, data *D, model *M) { /* Construct cdf */ double *cdf = malloc(sizeof(double) * n1); + if (cdf == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (j = 0; j < n1; j++) { cdf[j] = 1.0 * (j) / (1.0 * n1); @@ -61,6 +73,10 @@ void generate_model_continuum_devel(opts *options, data *D, model *M) { /* Construct a weight */ double *w = malloc(sizeof(double) * n1); + if (w == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } M->continuum[i] = 0.0; ns = 0.0; @@ -78,6 +94,10 @@ void generate_model_continuum_devel(opts *options, data *D, model *M) { int count,k; double *pdf = malloc(sizeof(double) * 20); + if (pdf == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (k = 0; k < 20; k++) { pdf[k] = 0; } diff --git a/src/models/continuum_fft.c b/src/models/continuum_fft.c index 1c93878..050d1a5 100644 --- a/src/models/continuum_fft.c +++ b/src/models/continuum_fft.c @@ -8,6 +8,10 @@ void generate_model_continuum_fft(opts *options, data *D, model *M) { int i; double *v = malloc(sizeof(double) * D->N); + if (v == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double cutoff; gsl_fft_real_wavetable * real; diff --git a/src/models/continuum_histogram.c b/src/models/continuum_histogram.c index de3b283..1de5a02 100644 --- a/src/models/continuum_histogram.c +++ b/src/models/continuum_histogram.c @@ -6,6 +6,10 @@ void generate_model_continuum_histogram(opts *options, data *D, model *M) { int i,j; stats *S1; double *v1 = malloc(sizeof(double) * D->N); + if (v1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int n1; for (i = 0; i < D->N; i += 1) { n1 = 0; diff --git a/src/models/continuum_logboxcar.c b/src/models/continuum_logboxcar.c index d093fce..b4f7ace 100644 --- a/src/models/continuum_logboxcar.c +++ b/src/models/continuum_logboxcar.c @@ -5,6 +5,10 @@ void generate_model_continuum_logboxcar(opts *options, data *D, model *M) { int i,j; stats *S1; double *v1 = malloc(sizeof(double) * D->N); + if (v1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int n1; for (i = 0; i < D->N; i += 1) { diff --git a/src/models/continuum_peak_boxcar.c b/src/models/continuum_peak_boxcar.c index f7b31bc..61d75aa 100644 --- a/src/models/continuum_peak_boxcar.c +++ b/src/models/continuum_peak_boxcar.c @@ -5,6 +5,10 @@ void generate_model_continuum_peak_boxcar(opts *options, data *D, model *M) { int i,j; stats *S1 = 0; double *v1 = malloc(sizeof(double) * D->N); + if (v1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int n1; for (i = 0; i < D->N; i += 1) { diff --git a/src/models/continuum_robust_linear.c b/src/models/continuum_robust_linear.c index c2eb46b..ca861d7 100644 --- a/src/models/continuum_robust_linear.c +++ b/src/models/continuum_robust_linear.c @@ -8,6 +8,10 @@ void generate_model_continuum_robust_linear(opts *options, data *D, model *M) { double *y; int *count = malloc(sizeof(int) * D->N); + if (count == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i,j,k = 0,z = 0; for (i = 0; i < D->N; i++) { @@ -16,7 +20,15 @@ void generate_model_continuum_robust_linear(opts *options, data *D, model *M) { for (i = 0; i < D->N; i++) { x = malloc(sizeof(double) * (options->continuum_box + 1)); + if (x == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } y = malloc(sizeof(double) * (options->continuum_box + 1)); + if (y == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } k = 0; for (j = -1 * (int) options->continuum_box / 2; j <= (int) options->continuum_box / 2; j++) { z = i + j; diff --git a/src/models/deblend_nlls.c b/src/models/deblend_nlls.c index 16cb4d3..a5f4be6 100644 --- a/src/models/deblend_nlls.c +++ b/src/models/deblend_nlls.c @@ -22,14 +22,50 @@ void deblend_lines_nlls(data *D, model *M) { for (i = 1; i < M->L->b; i++) { B = 1; m = malloc(B * sizeof(double)); + if (m == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } s = malloc(B * sizeof(double)); + if (s == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } F = malloc(B * sizeof(double)); + if (F == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } dm= malloc(B * sizeof(double)); + if (dm == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } ds= malloc(B * sizeof(double)); + if (ds == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } dF= malloc(B * sizeof(double)); + if (dF == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } vm= malloc(B * sizeof(int)); + if (vm == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } vs= malloc(B * sizeof(int)); + if (vs == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } vF= malloc(B * sizeof(int)); + if (vF == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (j = 0; j < M->L->l; j++) { if (M->L->blend_group[j] == i) { diff --git a/src/models/line_isolated_gaussian.c b/src/models/line_isolated_gaussian.c index 2c7681b..5915be6 100644 --- a/src/models/line_isolated_gaussian.c +++ b/src/models/line_isolated_gaussian.c @@ -10,6 +10,10 @@ void measure_lines_fixedmean_isolation_gaussian(data *D, model *M) { int iterations; double *y = malloc(sizeof(double) * D->N); + if (y == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } /* Subtract the current model from the data. */ for (j = 0; j < M->N; j++) { diff --git a/src/models/line_nonparametric.c b/src/models/line_nonparametric.c index 91b4e6e..dcea395 100644 --- a/src/models/line_nonparametric.c +++ b/src/models/line_nonparametric.c @@ -28,7 +28,15 @@ void measure_lines_nonparametric(data *D, model *M) { int envelope_N = 5; int envelope_i = 0; double *envelope_X = malloc(sizeof(double) * envelope_N); + if (envelope_X == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double *envelope_Y = malloc(sizeof(double) * envelope_N); + if (envelope_Y == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } double x1,x2; double y1,y2; double dy1,dy2; diff --git a/src/models/line_pre.c b/src/models/line_pre.c index 02fbd12..08f1c25 100644 --- a/src/models/line_pre.c +++ b/src/models/line_pre.c @@ -325,6 +325,10 @@ void measure_lines_PRE_second_version(data *D, model *M) { dwarf_lines = append_lines(dwarf_lines,D->x[max_x]); dwarf_lines->flags[dwarf_lines->l - 1] |= ROBO_FIT_BLEND; dwarf_lines->comment[dwarf_lines->l - 1] = malloc(sizeof(char) * 100); + if (dwarf_lines->comment[dwarf_lines->l - 1] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(dwarf_lines->comment[dwarf_lines->l - 1],100, "Dwarf line at %g adjacent to line at %g(%d)", D->x[max_x],M->L->mp[i],i); @@ -403,6 +407,10 @@ void measure_lines_PRE_second_version(data *D, model *M) { dwarf_lines->flags[dwarf_lines->l - 1] |= ROBO_FIT_BLEND; dwarf_lines->comment[dwarf_lines->l - 1] = malloc(sizeof(char) * 100); + if (dwarf_lines->comment[dwarf_lines->l - 1] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(dwarf_lines->comment[dwarf_lines->l - 1],100, "Dwarf line at %g adjacent to line at %g(%d)", D->x[max_x],M->L->mp[i],i); diff --git a/src/models/line_threestage_gaussian.c b/src/models/line_threestage_gaussian.c index 0bd36c3..5bb5768 100644 --- a/src/models/line_threestage_gaussian.c +++ b/src/models/line_threestage_gaussian.c @@ -17,17 +17,65 @@ void measure_lines_threestage(data *D, model *M) { for (j = 0; j < M->L->l; j++) { B = 1; m = malloc(B * sizeof(double)); + if (m == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } s = malloc(B * sizeof(double)); + if (s == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } F = malloc(B * sizeof(double)); + if (F == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } eta = malloc(B * sizeof(double)); + if (eta == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } dm= malloc(B * sizeof(double)); + if (dm == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } ds= malloc(B * sizeof(double)); + if (ds == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } dF= malloc(B * sizeof(double)); + if (dF == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } deta = malloc(B * sizeof(double)); + if (deta == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } vm= malloc(B * sizeof(int)); + if (vm == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } vs= malloc(B * sizeof(int)); + if (vs == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } vF= malloc(B * sizeof(int)); + if (vF == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } veta = malloc(B * sizeof(int)); + if (veta == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } m[B-1] = M->L->mp[j]; s[B-1] = M->L->sp[j]; diff --git a/src/nlls-gaussfit.c b/src/nlls-gaussfit.c index 0470a0a..216535c 100644 --- a/src/nlls-gaussfit.c +++ b/src/nlls-gaussfit.c @@ -106,16 +106,44 @@ int gaussfit(double *X, double *Y, double *E, int N, *A = *A * pow(*s * sqrt(2 * M_PI),-1); /* Allocate space for matrices. */ dB = malloc(N * sizeof(double)); + if (dB == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } a = malloc(N * sizeof(double *)); + if (a == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } a[0] = malloc(N * 3 * sizeof(double)); + if (a[0] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (i = 1; i < N; i++) { a[i] = a[0] + i * 3; } C = malloc(3 * sizeof(double *)); + if (C == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } C[0] = malloc(9 * sizeof(double)); + if (C[0] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } ata = malloc(3 * sizeof(double *)); + if (ata == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } ata[0] = malloc(9 * sizeof(double)); + if (ata[0] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (i = 1; i < 3; i++) { C[i] = C[0] + i * 3; ata[i] = ata[0] + i * 3; diff --git a/src/nlls-multigauss.c b/src/nlls-multigauss.c index 42d5a28..eda32ae 100644 --- a/src/nlls-multigauss.c +++ b/src/nlls-multigauss.c @@ -57,18 +57,46 @@ typedef struct { multigauss_solver *alloc_multigauss_solver(double m, double s, double A, int N) { multigauss_solver *S = malloc(sizeof(multigauss_solver)); + if (S == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; S->a = malloc(N * sizeof(double *)); + if (S->a == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } S->a[0] = malloc(N * 3 * sizeof(double)); + if (S->a[0] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (i = 1; i < N; i++) { S->a[i] = S->a[0] + i * 3; } S->C = malloc(3 * sizeof(double *)); + if (S->C == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } S->C[0] = malloc(9 * sizeof(double)); + if (S->C[0] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } S->ata = malloc(3 * sizeof(double *)); + if (S->ata == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } S->ata[0] = malloc(9 * sizeof(double)); + if (S->ata[0] == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (i = 1; i < 3; i++) { S->C[i] = S->C[0] + i * 3; S->ata[i] = S->ata[0] + i * 3; @@ -133,8 +161,20 @@ int multigauss(double *X, double *Y, double *E, int N, double old_chi = 99e99; /* Save initial values in case we need to reset. */ mi = malloc(sizeof(double) * M); + if (mi == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } si = malloc(sizeof(double) * M); + if (si == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } Ai = malloc(sizeof(double) * M); + if (Ai == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } for (j = 0; j < M; j++) { mi[j] = m[j]; si[j] = s[j]; diff --git a/src/noise.c b/src/noise.c index e8761ca..4db9274 100644 --- a/src/noise.c +++ b/src/noise.c @@ -22,6 +22,10 @@ void generate_noise_model_boxcar(opts *options, data *D, model *M) { int i,j; stats *S1; double *v1 = malloc(sizeof(double) * D->N); + if (v1 == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int n1; for (i = 0; i < D->N; i += 1) { diff --git a/src/rv.c b/src/rv.c index f683503..94dd1d0 100644 --- a/src/rv.c +++ b/src/rv.c @@ -157,6 +157,10 @@ void measure_radial_velocity(opts *options, data *D, model *M) { rv_options->max_order = 0; rv_options->supplied_errors = 0; rv_options->path_base = malloc(32 * sizeof(char)); + if (rv_options->path_base == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } rv_options->line_list_filename = NULL; rv_options->strict = 0; rv_options->fits_IO = 0; @@ -166,15 +170,39 @@ void measure_radial_velocity(opts *options, data *D, model *M) { rv_options->command_line = NULL; rv_options->continuum_model_name = malloc(32 * sizeof(char)); + if (rv_options->continuum_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(rv_options->continuum_model_name,32 * sizeof(char),"%s",options->continuum_model_name); rv_options->line_model_name = malloc(32 * sizeof(char)); + if (rv_options->line_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(rv_options->line_model_name,32 * sizeof(char),"pre"); rv_options->noise_model_name = malloc(32 * sizeof(char)); + if (rv_options->noise_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } snprintf(rv_options->noise_model_name,32 * sizeof(char),"%s",options->noise_model_name); rv_options->deblend_model_name = malloc(32 * sizeof(char)); + if (rv_options->deblend_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } rv_options->function_model_name = malloc(32 * sizeof(char)); + if (rv_options->function_model_name == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } rv_data = malloc(sizeof(data)); + if (rv_data == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } rv_data->N = D->N; rv_data->x = vector_copy(D->x , D->N); rv_data->y = vector_copy(D->y , D->N); diff --git a/src/vectors.c b/src/vectors.c index 8d993a7..89f1f09 100644 --- a/src/vectors.c +++ b/src/vectors.c @@ -6,6 +6,10 @@ double *vector_add(double *A, double *B, int N) { double *O = malloc(sizeof(double) * N); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; @@ -18,6 +22,10 @@ double *vector_add(double *A, double *B, int N) { double *vector_subtract(double *A, double *B, int N) { double *O = malloc(sizeof(double) * N); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; @@ -30,6 +38,10 @@ double *vector_subtract(double *A, double *B, int N) { double *vector_subtract_constant(double *A, double B, int N) { double *O = malloc(sizeof(double) * N); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; @@ -42,6 +54,10 @@ double *vector_subtract_constant(double *A, double B, int N) { double *vector_multiply(double *A, double *B, int N) { double *O = malloc(sizeof(double) * N); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory for O\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; @@ -54,6 +70,10 @@ double *vector_multiply(double *A, double *B, int N) { double *vector_divide(double *A, double *B, int N) { double *O = malloc(sizeof(double) * N); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; @@ -66,6 +86,10 @@ double *vector_divide(double *A, double *B, int N) { double *vector_constant(double V, int N) { double *O = malloc(sizeof(double) * N); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; for (i = 0; i < N ; i++) { O[i] = V; @@ -76,6 +100,10 @@ double *vector_constant(double V, int N) { double *vector_copy(double *A, int N) { double *O = malloc(sizeof(double) * N); + if (O == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } int i; for (i = 0; i < N; i++) { O[i] = A[i]; From 0474b836b525b9e592c0065fdf7242bf5c11daeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gabriel=20Sz=C3=A1sz?= Date: Thu, 28 Nov 2024 21:15:40 +0100 Subject: [PATCH 4/4] Fix additional memory allocation errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Lukas Kueß (@iamasciencer) has encountered enigmatic buffer overflow errors when testing ROBOSPECT on Ubuntu 24.02 LTS. It turned out that Ubuntu 24.02 LTS uses fortified strings by default and since the ROBOSPECT's string memory allocation handling is suboptimal, it did not comply the strict rules of fortified strings. I had to rewrite several parts of config.c to make this work properly. --- src/config.c | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/src/config.c b/src/config.c index 527ccb0..d215963 100644 --- a/src/config.c +++ b/src/config.c @@ -76,9 +76,6 @@ void free_options (opts *O) { } O->log = stderr; } - if (O->command_name) { - free(O->command_name); - } if (O->command_line) { free(O->command_line); } @@ -371,8 +368,8 @@ char * get_time() { void set_options(opts *O, int argc, char *argv[]) { char c = 0; - int i = 0; - int j = 0; + int i, pos; + int command_line_len; int opt_index; /* Rework this to use a better argument list for long options */ @@ -417,18 +414,23 @@ void set_options(opts *O, int argc, char *argv[]) { {0,0,0,0} }; + /* Store command name into the option struct. */ + O->command_name = argv[0]; + /* Store command line into the option struct. */ - i = 0; - O->command_name = realloc(O->command_name,sizeof(char) * (i + strlen(argv[j]) + 2)); - O->command_name = strcat(O->command_name,argv[j]); - for (j = 0; j < argc; j++) { - O->command_line = realloc(O->command_line,sizeof(char) * (i + strlen(argv[j]) + 2)); - i = i + strlen(argv[j]) + 2; - if (j > 0) { - O->command_line = strcat(O->command_line," "); - } - O->command_line = strcat(O->command_line,argv[j]); + command_line_len = 0; + for (i = 0 ; i < argc; i++) { + command_line_len += strlen(argv[i]) + 1; } + O->command_line = malloc(command_line_len + 1); + if (O->command_line == NULL) { + fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); + exit(EXIT_FAILURE); + } + for (i = 0, pos = 0; i < argc; i++) { + pos += sprintf(O->command_line + pos, "%s ", argv[i]); + } + /* Parse options. */ while ((c = getopt_long(argc,argv,"hFf:e:E:w:p:V:r:R:T:i:d:L:C:N:M:D:v:P:lz:x:y:1AI2:Q:3:45:6:7:8:", long_options,&opt_index)) != -1) { @@ -572,12 +574,7 @@ void set_options(opts *O, int argc, char *argv[]) { /* Load input file or read from stdin */ if (argv[optind] == NULL) { - O->infilename = malloc(32 * sizeof(char)); - if (O->infilename == NULL) { - fprintf(stderr, "robospect: %s: %d: Cannot allocate memory\n", __FILE__, __LINE__); - exit(EXIT_FAILURE); - } - snprintf(O->infilename,32,"/dev/stdin"); + O->infilename = "/dev/stdin"; } else { O->infilename = argv[optind];