Skip to content

Commit 4564a09

Browse files
authored
lib/arraystats: re-enable "Discont" algorithm (#5529)
Addresses heap buffer overflow in previously disabled 'Discont' algorithm. The immediate cause was too small allocation of variable `num` in `AS_class_discont()`, which was fixed by an increase of its size (broadly mirroring the original Fortran code). This fix was complemented by some code related improvements: - Code clean up and restructure of `AS_class_discont()` - Re-enable "dis" algorithm in v.class and d.vect.thematic - Remove realloc of classbreak, which wasn’t necessary and would need complicated solution to work See: https://lists.osgeo.org/pipermail/grass-dev/2008-July/038951.html Fixes: #5486
1 parent 18980e9 commit 4564a09

File tree

5 files changed

+146
-155
lines changed

5 files changed

+146
-155
lines changed

display/d.vect.thematic/main.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,11 +119,10 @@ int main(int argc, char **argv)
119119
algo_opt->options = "int,std,qua,equ,dis";
120120
algo_opt->description = _("Algorithm to use for classification");
121121
desc = NULL;
122-
G_asprintf(&desc, "int;%s;std;%s;qua;%s;equ;%s", _("simple intervals"),
123-
_("standard deviations"), _("quantiles"),
124-
_("equiprobable (normal distribution)"));
122+
G_asprintf(&desc, "int;%s;std;%s;qua;%s;equ;%s;dis;%s",
123+
_("simple intervals"), _("standard deviations"), _("quantiles"),
124+
_("equiprobable (normal distribution)"), _("discontinuities"));
125125
algo_opt->descriptions = desc;
126-
/*currently disabled because of bugs "dis;discontinuities"); */
127126
algo_opt->guisection = _("Classes");
128127

129128
nbclass_opt = G_define_option();

include/grass/defs/arraystats.h

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,17 @@
22
#define GRASS_ARRAYSTATSDEFS_H
33

44
/* basic.c */
5-
void AS_eqdrt(double[], double[], int, int, double *);
6-
void AS_basic_stats(double *, int, struct GASTATS *);
5+
void AS_eqdrt(double[], double[], int, int, double *, double *, double *);
6+
void AS_basic_stats(const double[], int, struct GASTATS *);
77

88
/* class.c */
99
int AS_option_to_algorithm(const struct Option *);
10-
double AS_class_apply_algorithm(int, double *, int, int *, double *);
11-
int AS_class_interval(double *, int, int, double *);
12-
int AS_class_quant(double *, int, int, double *);
13-
double AS_class_discont(double *, int, int, double *);
14-
double AS_class_stdev(double *, int, int, double *);
15-
int AS_class_equiprob(double *, int, int *, double *);
16-
int AS_class_frequencies(double *, int, int, double *, int *);
10+
double AS_class_apply_algorithm(int, const double[], int, int *, double[]);
11+
int AS_class_interval(const double[], int, int, double[]);
12+
int AS_class_quant(const double[], int, int, double[]);
13+
double AS_class_discont(const double[], int, int, double[]);
14+
double AS_class_stdev(const double[], int, int, double[]);
15+
int AS_class_equiprob(const double[], int, int *, double[]);
16+
int AS_class_frequencies(const double[], int, int, double[], int[]);
1717

1818
#endif

lib/arraystats/basic.c

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
#include <math.h>
2+
23
#include <grass/arraystats.h>
4+
#include <grass/gis.h>
35

46
/*provides basic univar stats */
5-
void AS_basic_stats(double *data, int count, struct GASTATS *stats)
7+
void AS_basic_stats(const double data[], int count, struct GASTATS *stats)
68
{
79
int i = 1;
810
double sum = 0, sumsq = 0, sumabs = 0;
@@ -34,31 +36,40 @@ void AS_basic_stats(double *data, int count, struct GASTATS *stats)
3436
return;
3537
}
3638

37-
void AS_eqdrt(double vectx[], double vecty[], int i1, int i2, double *vabc)
39+
void AS_eqdrt(double vectx[], double vecty[], int i1, int i2, double *a,
40+
double *b, double *c)
3841
{
39-
double bn = 0, bd = 0, x1 = 0, y1 = 0;
42+
double x1 = vectx[i1];
43+
double y1 = vecty[i1];
44+
double x2 = vectx[i2];
45+
double y2 = vecty[i2];
4046

41-
vabc[0] = 0;
42-
vabc[1] = 0;
43-
vabc[2] = 0;
4447
if (i1 == 0) {
45-
x1 = 0;
46-
y1 = 0;
48+
x1 = 0.0;
49+
y1 = 0.0;
4750
}
4851
else {
4952
x1 = vectx[i1];
5053
y1 = vecty[i1];
5154
}
52-
bn = y1 - vecty[i2];
53-
bd = x1 - vectx[i2];
54-
if (bd != 0) {
55-
vabc[1] = bn / bd;
56-
vabc[0] = y1 - vabc[1] * x1;
57-
return;
55+
56+
*a = 0.0;
57+
*b = 0.0;
58+
*c = 0.0;
59+
60+
double bn = y1 - y2;
61+
double bd = x1 - x2;
62+
63+
if (fabs(bd) < GRASS_EPSILON) {
64+
if (fabs(bn) < GRASS_EPSILON) {
65+
G_debug(3, "Points are equal\n");
66+
}
67+
else {
68+
*c = x1;
69+
}
70+
}
71+
else {
72+
*b = bn / bd;
73+
*a = y1 - *b * x1;
5874
}
59-
if (bn != 0)
60-
vabc[2] = x1;
61-
else
62-
G_debug(3, "Points are equal\n");
63-
return;
6475
}

0 commit comments

Comments
 (0)