X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fregression.c;h=b4448dd9e58ead03cb61cf3d5e5b3c97201b1edf;hb=114cd2dc25959a7927730e502300321624f8c07b;hp=28618f12b0a89a2a04a04b10d2f8bd6425d20cc2;hpb=9420449c40bb1307f6c31e50b61ba03825680e3a;p=pspp diff --git a/src/language/stats/regression.c b/src/language/stats/regression.c index 28618f12b0..b4448dd9e5 100644 --- a/src/language/stats/regression.c +++ b/src/language/stats/regression.c @@ -159,7 +159,7 @@ save_trans_free (void *aux) return true; } -static int +static enum trns_result save_trans_func (void *aux, struct ccase **c, casenumber x UNUSED) { struct save_trans_data *save_trans_data = aux; @@ -175,14 +175,14 @@ save_trans_func (void *aux, struct ccase **c, casenumber x UNUSED) { if (ws->pred_idx != -1) { - double pred = case_data_idx (in, ws->extras * k + ws->pred_idx)->f; - case_data_rw (*c, ws->predvars[k])->f = pred; + double pred = case_num_idx (in, ws->extras * k + ws->pred_idx); + *case_num_rw (*c, ws->predvars[k]) = pred; } if (ws->res_idx != -1) { - double resid = case_data_idx (in, ws->extras * k + ws->res_idx)->f; - case_data_rw (*c, ws->residvars[k])->f = resid; + double resid = case_num_idx (in, ws->extras * k + ws->res_idx); + *case_num_rw (*c, ws->residvars[k]) = resid; } } case_unref (in); @@ -191,7 +191,6 @@ save_trans_func (void *aux, struct ccase **c, casenumber x UNUSED) return TRNS_CONTINUE; } - int cmd_regression (struct lexer *lexer, struct dataset *ds) { @@ -450,7 +449,12 @@ cmd_regression (struct lexer *lexer, struct dataset *ds) memcpy (save_trans_data->ws, &workspace, sizeof (workspace)); save_trans_data->n_dep_vars = regression.n_dep_vars; - add_transformation (ds, save_trans_func, save_trans_free, save_trans_data); + static const struct trns_class trns_class = { + .name = "REGRESSION", + .execute = save_trans_func, + .destroy = save_trans_free, + }; + add_transformation (ds, &trns_class, save_trans_data); } @@ -671,8 +675,7 @@ run_regression_get_models (const struct regression *cmd, bool output) { size_t i; - struct linreg **models = NULL; - struct model_container *model_container = xzalloc (sizeof (*model_container) * cmd->n_vars); + struct model_container *model_container = XCALLOC (cmd->n_vars, struct model_container); struct ccase *c; struct covariance *cov; @@ -706,8 +709,13 @@ run_regression_get_models (const struct regression *cmd, size_t n_all_vars = get_n_all_vars (cmd); const struct variable **all_vars = xnmalloc (n_all_vars, sizeof (*all_vars)); - double *means = xnmalloc (n_all_vars, sizeof (*means)); - + /* In the (rather pointless) case where the dependent variable is + the independent variable, n_all_vars == 1. + However this would result in a buffer overflow so we must + over-allocate the space required in this malloc call. + See bug #58599 */ + double *means = xnmalloc (n_all_vars <= 1 ? 2 : n_all_vars, + sizeof (*means)); fill_all_vars (all_vars, cmd); cov = covariance_1pass_create (n_all_vars, all_vars, dict_get_weight (dataset_dict (cmd->ds)), @@ -726,7 +734,7 @@ run_regression_get_models (const struct regression *cmd, casereader_destroy (r); } - models = xcalloc (cmd->n_dep_vars, sizeof (*models)); + struct linreg **models = XCALLOC (cmd->n_dep_vars, struct linreg*); for (int k = 0; k < cmd->n_dep_vars; k++) { @@ -822,14 +830,14 @@ run_regression (const struct regression *cmd, if (cmd->pred) { double pred = linreg_predict (models[k], vals, n_indep); - case_data_rw_idx (outc, k * ws->extras + ws->pred_idx)->f = pred; + *case_num_rw_idx (outc, k * ws->extras + ws->pred_idx) = pred; } if (cmd->resid) { - double obs = case_data (c, linreg_dep_var (models[k]))->f; + double obs = case_num (c, linreg_dep_var (models[k])); double res = linreg_residual (models[k], obs, vals, n_indep); - case_data_rw_idx (outc, k * ws->extras + ws->res_idx)->f = res; + *case_num_rw_idx (outc, k * ws->extras + ws->res_idx) = res; } free (vals); free (vars);