X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Flanguage%2Fstats%2Fdescriptives.c;h=413826cc9cdaa64c7e9b10d503f80ceae15dc57c;hb=894768ac889ab6cb41cc47a5d14306462505927c;hp=54bc49d946a064bd3c4eee8ffdab962d611733c3;hpb=fa1fffd5c789d9c7875fc3bdf556eaf017cf524e;p=pspp diff --git a/src/language/stats/descriptives.c b/src/language/stats/descriptives.c index 54bc49d946..413826cc9c 100644 --- a/src/language/stats/descriptives.c +++ b/src/language/stats/descriptives.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 1997-2000, 2009-2012 Free Software Foundation, Inc. + Copyright (C) 1997-2000, 2009-2013 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -397,6 +397,13 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds) } } + /* It would be better to handle Z scores correctly (however we define + that) when TEMPORARY is in effect, but in the meantime this at least + prevents a use-after-free error. See bug #38786. */ + if (proc_make_temporary_transformations_permanent (ds)) + msg (SW, _("DESCRIPTIVES with Z scores ignores TEMPORARY. " + "Temporary transformations will be made permanent.")); + proto = caseproto_create (); for (i = 0; i < 1 + 2 * z_cnt; i++) proto = caseproto_add_width (proto, 0); @@ -434,7 +441,8 @@ cmd_descriptives (struct lexer *lexer, struct dataset *ds) dsc->vars[i].moments = moments_create (dsc->max_moment); /* Data pass. */ - grouper = casegrouper_create_splits (proc_open (ds), dict); + grouper = casegrouper_create_splits (proc_open_filtering (ds, z_cnt == 0), + dict); while (casegrouper_get_next_group (grouper, &group)) calc_descriptives (dsc, group, ds); ok = casegrouper_destroy (grouper); @@ -512,7 +520,7 @@ try_name (const struct dictionary *dict, struct dsc_proc *dsc, for (i = 0; i < dsc->var_cnt; i++) { struct dsc_var *dsc_var = &dsc->vars[i]; - if (dsc_var->z_name != NULL && !strcasecmp (dsc_var->z_name, name)) + if (dsc_var->z_name != NULL && !utf8_strcasecmp (dsc_var->z_name, name)) return false; } return true; @@ -689,6 +697,8 @@ descriptives_trns_free (void *trns_) casereader_destroy (t->z_reader); assert((t->missing_type != DSC_LISTWISE) ^ (t->vars != NULL)); free (t->vars); + free (t); + return ok; } @@ -732,11 +742,13 @@ setup_z_trns (struct dsc_proc *dsc, struct dataset *ds) { struct dsc_z_score *z; struct variable *dst_var; + char *label; dst_var = dict_create_var_assert (dataset_dict (ds), dv->z_name, 0); - var_set_label (dst_var, - xasprintf (_("Z-score of %s"),var_to_string (dv->v)), - false); + + label = xasprintf (_("Z-score of %s"),var_to_string (dv->v)); + var_set_label (dst_var, label, false); + free (label); z = &t->z_scores[cnt++]; z->src_var = dv->v; @@ -1017,7 +1029,7 @@ descriptives_compare_dsc_vars (const void *a_, const void *b_, const void *dsc_) int result; if (dsc->sort_by_stat == DSC_NAME) - result = strcasecmp (var_get_name (a->v), var_get_name (b->v)); + result = utf8_strcasecmp (var_get_name (a->v), var_get_name (b->v)); else { double as = a->stats[dsc->sort_by_stat];