Commit 43e9bc1c authored by Raúl Marín's avatar Raúl Marín

Avoid undefined behaviour in gserialized_estimate

Closes #4190
Closes https://github.com/postgis/postgis/pull/315



git-svn-id: http://svn.osgeo.org/postgis/trunk@17022 b70326c6-7e19-0410-871a-916f4a2858ee
parent 5f36cd63
Pipeline #36750623 passed with stage
in 32 minutes and 17 seconds
......@@ -37,6 +37,7 @@ PostGIS 3.0.0
ST_LocateBetween and ST_LocateBetweenElevations (Darafei Praliaskouski)
- #2767, Documentation for AddRasterConstraint optional parameters (Sunveer Singh)
- #4326, Allocate enough memory in gidx_to_string (Raúl Marín)
- #4190, Avoid undefined behaviour in gserialized_estimate (Raúl Marín)
PostGIS 2.5.0
2018/09/23
......
......@@ -646,7 +646,9 @@ nd_box_expand(ND_BOX *nd_box, double expansion_factor)
for ( d = 0; d < ND_DIMS; d++ )
{
size = nd_box->max[d] - nd_box->min[d];
if ( size <= 0 ) continue;
/* Avoid expanding boxes that are either too wide or too narrow*/
if (size < MIN_DIMENSION_WIDTH || size > MAX_DIMENSION_WIDTH)
continue;
nd_box->min[d] -= size * expansion_factor / 2;
nd_box->max[d] += size * expansion_factor / 2;
}
......@@ -673,18 +675,26 @@ nd_box_overlap(const ND_STATS *nd_stats, const ND_BOX *nd_box, ND_IBOX *nd_ibox)
double smin = nd_stats->extent.min[d];
double smax = nd_stats->extent.max[d];
double width = smax - smin;
int size = roundf(nd_stats->size[d]);
/* ... find cells the box overlaps with in this dimension */
nd_ibox->min[d] = floor(size * (nd_box->min[d] - smin) / width);
nd_ibox->max[d] = floor(size * (nd_box->max[d] - smin) / width);
if (width < MIN_DIMENSION_WIDTH)
{
nd_ibox->min[d] = nd_ibox->max[d] = nd_stats->extent.min[d];
}
else
{
int size = (int)roundf(nd_stats->size[d]);
/* ... find cells the box overlaps with in this dimension */
nd_ibox->min[d] = floor(size * (nd_box->min[d] - smin) / width);
nd_ibox->max[d] = floor(size * (nd_box->max[d] - smin) / width);
POSTGIS_DEBUGF(5, " stats: dim %d: min %g: max %g: width %g", d, smin, smax, width);
POSTGIS_DEBUGF(5, " overlap: dim %d: (%d, %d)", d, nd_ibox->min[d], nd_ibox->max[d]);
POSTGIS_DEBUGF(5, " stats: dim %d: min %g: max %g: width %g", d, smin, smax, width);
POSTGIS_DEBUGF(5, " overlap: dim %d: (%d, %d)", d, nd_ibox->min[d], nd_ibox->max[d]);
/* Push any out-of range values into range */
nd_ibox->min[d] = Max(nd_ibox->min[d], 0);
nd_ibox->max[d] = Min(nd_ibox->max[d], size-1);
/* Push any out-of range values into range */
nd_ibox->min[d] = Max(nd_ibox->min[d], 0);
nd_ibox->max[d] = Min(nd_ibox->max[d], size - 1);
}
}
return true;
}
......@@ -1893,7 +1903,9 @@ Datum gserialized_analyze_nd(PG_FUNCTION_ARGS)
POSTGIS_DEBUGF(3, " attribute stat target: %d", attr->attstattarget);
/* Setup the minimum rows and the algorithm function */
/* Setup the minimum rows and the algorithm function.
* 300 matches the default value set in
* postgresql/src/backend/commands/analyze.c */
stats->minrows = 300 * stats->attr->attstattarget;
stats->compute_stats = compute_gserialized_stats;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment