Typecasts added to the GeoPoly extension to avoid harmless UBSAN warnings.

FossilOrigin-Name: a1f6a093ac4a2de8c5b02c30fe57e09770460fd5bdddfe9c7a9a24fb83a6b491
This commit is contained in:
drh 2019-01-18 19:33:56 +00:00
parent 451297752c
commit d00ad9a656
3 changed files with 58 additions and 49 deletions

View File

@ -124,6 +124,14 @@ struct GeoPoly {
*/
#define GEOPOLY_SZ(N) (sizeof(GeoPoly) + sizeof(GeoCoord)*2*((N)-4))
/* Macros to access coordinates of a GeoPoly.
** We have to use these macros, rather than just say p->a[i] in order
** to silence (incorrect) UBSAN warnings if the array index is too large.
*/
#define GeoX(P,I) (((GeoCoord*)(P)->a)[(I)*2])
#define GeoY(P,I) (((GeoCoord*)(P)->a)[(I)*2+1])
/*
** State of a parse of a GeoJSON input.
*/
@ -316,8 +324,9 @@ static GeoPoly *geopolyFuncParam(
memcpy(p->hdr, a, nByte);
if( a[0] != *(unsigned char*)&x ){
int ii;
for(ii=0; ii<nVertex*2; ii++){
geopolySwab32((unsigned char*)&p->a[ii]);
for(ii=0; ii<nVertex; ii++){
geopolySwab32((unsigned char*)&GeoX(p,ii));
geopolySwab32((unsigned char*)&GeoY(p,ii));
}
p->hdr[0] ^= 1;
}
@ -376,9 +385,9 @@ static void geopolyJsonFunc(
int i;
sqlite3_str_append(x, "[", 1);
for(i=0; i<p->nVertex; i++){
sqlite3_str_appendf(x, "[%!g,%!g],", p->a[i*2], p->a[i*2+1]);
sqlite3_str_appendf(x, "[%!g,%!g],", GeoX(p,i), GeoY(p,i));
}
sqlite3_str_appendf(x, "[%!g,%!g]]", p->a[0], p->a[1]);
sqlite3_str_appendf(x, "[%!g,%!g]]", GeoX(p,0), GeoY(p,0));
sqlite3_result_text(context, sqlite3_str_finish(x), -1, sqlite3_free);
sqlite3_free(p);
}
@ -405,10 +414,10 @@ static void geopolySvgFunc(
char cSep = '\'';
sqlite3_str_appendf(x, "<polyline points=");
for(i=0; i<p->nVertex; i++){
sqlite3_str_appendf(x, "%c%g,%g", cSep, p->a[i*2], p->a[i*2+1]);
sqlite3_str_appendf(x, "%c%g,%g", cSep, GeoX(p,i), GeoY(p,i));
cSep = ' ';
}
sqlite3_str_appendf(x, " %g,%g'", p->a[0], p->a[1]);
sqlite3_str_appendf(x, " %g,%g'", GeoX(p,0), GeoY(p,0));
for(i=1; i<argc; i++){
const char *z = (const char*)sqlite3_value_text(argv[i]);
if( z && z[0] ){
@ -453,12 +462,12 @@ static void geopolyXformFunc(
int ii;
if( p ){
for(ii=0; ii<p->nVertex; ii++){
x0 = p->a[ii*2];
y0 = p->a[ii*2+1];
x0 = GeoX(p,ii);
y0 = GeoY(p,ii);
x1 = (GeoCoord)(A*x0 + B*y0 + E);
y1 = (GeoCoord)(C*x0 + D*y0 + F);
p->a[ii*2] = x1;
p->a[ii*2+1] = y1;
GeoX(p,ii) = x1;
GeoY(p,ii) = y1;
}
sqlite3_result_blob(context, p->hdr,
4+8*p->nVertex, SQLITE_TRANSIENT);
@ -477,12 +486,12 @@ static double geopolyArea(GeoPoly *p){
double rArea = 0.0;
int ii;
for(ii=0; ii<p->nVertex-1; ii++){
rArea += (p->a[ii*2] - p->a[ii*2+2]) /* (x0 - x1) */
* (p->a[ii*2+1] + p->a[ii*2+3]) /* (y0 + y1) */
rArea += (GeoX(p,ii) - GeoX(p,ii+1)) /* (x0 - x1) */
* (GeoY(p,ii) + GeoY(p,ii+1)) /* (y0 + y1) */
* 0.5;
}
rArea += (p->a[ii*2] - p->a[0]) /* (xN - x0) */
* (p->a[ii*2+1] + p->a[1]) /* (yN + y0) */
rArea += (GeoX(p,ii) - GeoX(p,0)) /* (xN - x0) */
* (GeoY(p,ii) + GeoY(p,0)) /* (yN + y0) */
* 0.5;
return rArea;
}
@ -529,13 +538,13 @@ static void geopolyCcwFunc(
if( p ){
if( geopolyArea(p)<0.0 ){
int ii, jj;
for(ii=2, jj=p->nVertex*2 - 2; ii<jj; ii+=2, jj-=2){
GeoCoord t = p->a[ii];
p->a[ii] = p->a[jj];
p->a[jj] = t;
t = p->a[ii+1];
p->a[ii+1] = p->a[jj+1];
p->a[jj+1] = t;
for(ii=1, jj=p->nVertex-1; ii<jj; ii++, jj--){
GeoCoord t = GeoX(p,ii);
GeoX(p,ii) = GeoX(p,jj);
GeoX(p,jj) = t;
t = GeoY(p,ii);
GeoY(p,ii) = GeoY(p,jj);
GeoY(p,jj) = t;
}
}
sqlite3_result_blob(context, p->hdr,
@ -595,8 +604,8 @@ static void geopolyRegularFunc(
p->hdr[3] = n&0xff;
for(i=0; i<n; i++){
double rAngle = 2.0*GEOPOLY_PI*i/n;
p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
p->a[i*2+1] = y + r*geopolySine(rAngle);
GeoX(p,i) = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
GeoY(p,i) = y + r*geopolySine(rAngle);
}
sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
sqlite3_free(p);
@ -633,13 +642,13 @@ static GeoPoly *geopolyBBox(
}
if( p ){
int ii;
mnX = mxX = p->a[0];
mnY = mxY = p->a[1];
mnX = mxX = GeoX(p,0);
mnY = mxY = GeoY(p,0);
for(ii=1; ii<p->nVertex; ii++){
double r = p->a[ii*2];
double r = GeoX(p,ii);
if( r<mnX ) mnX = (float)r;
else if( r>mxX ) mxX = (float)r;
r = p->a[ii*2+1];
r = GeoY(p,ii);
if( r<mnY ) mnY = (float)r;
else if( r>mxY ) mxY = (float)r;
}
@ -659,14 +668,14 @@ static GeoPoly *geopolyBBox(
pOut->hdr[1] = 0;
pOut->hdr[2] = 0;
pOut->hdr[3] = 4;
pOut->a[0] = mnX;
pOut->a[1] = mnY;
pOut->a[2] = mxX;
pOut->a[3] = mnY;
pOut->a[4] = mxX;
pOut->a[5] = mxY;
pOut->a[6] = mnX;
pOut->a[7] = mxY;
GeoX(pOut,0) = mnX;
GeoY(pOut,0) = mnY;
GeoX(pOut,1) = mxX;
GeoY(pOut,1) = mnY;
GeoX(pOut,2) = mxX;
GeoY(pOut,2) = mxY;
GeoX(pOut,3) = mnX;
GeoY(pOut,3) = mxY;
}else{
sqlite3_free(p);
aCoord[0].f = mnX;
@ -804,14 +813,14 @@ static void geopolyContainsPointFunc(
int ii;
if( p1==0 ) return;
for(ii=0; ii<p1->nVertex-1; ii++){
v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
p1->a[ii*2+2],p1->a[ii*2+3]);
v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
GeoX(p1,ii+1),GeoY(p1,ii+1));
if( v==2 ) break;
cnt += v;
}
if( v!=2 ){
v = pointBeneathLine(x0,y0,p1->a[ii*2],p1->a[ii*2+1],
p1->a[0],p1->a[1]);
v = pointBeneathLine(x0,y0,GeoX(p1,ii), GeoY(p1,ii),
GeoX(p1,0), GeoY(p1,0));
}
if( v==2 ){
sqlite3_result_int(context, 1);
@ -933,10 +942,10 @@ static void geopolyAddSegments(
unsigned int i;
GeoCoord *x;
for(i=0; i<(unsigned)pPoly->nVertex-1; i++){
x = pPoly->a + (i*2);
x = &GeoX(pPoly,i);
geopolyAddOneSegment(p, x[0], x[1], x[2], x[3], side, i);
}
x = pPoly->a + (i*2);
x = &GeoX(pPoly,i);
geopolyAddOneSegment(p, x[0], x[1], pPoly->a[0], pPoly->a[1], side, i);
}

View File

@ -1,5 +1,5 @@
C Fix\sproblems\scausing\sundefined\sleft-shift\soperations\sin\sthe\sfts3\ssnippet()\nfunction.
D 2019-01-18T19:26:48.918
C Typecasts\sadded\sto\sthe\sGeoPoly\sextension\sto\savoid\sharmless\sUBSAN\swarnings.
D 2019-01-18T19:33:56.463
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F Makefile.in 2a9d0331ab57c68173a4c2fe9046fe89c4d916a888e04dd7a2d36958c2bff777
@ -366,7 +366,7 @@ F ext/repair/test/checkfreelist01.test 3e8aa6aeb4007680c94a8d07b41c339aa635cc782
F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec
F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c
F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
F ext/rtree/geopoly.c 603ec9b72cd70cf18541339b6c7d47f304ac0d84c50294be6c6c6ae35acdb0a6
F ext/rtree/geopoly.c 061432bddc38c4c10c7e4ce940d581c886d65bb5814b4b65b46ad046aa85eaa2
F ext/rtree/rtree.c 57729cc19f3832e5f9051556af44ed264b5bd54b01543cd7e50d5143817b964c
F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412
F ext/rtree/rtree1.test 7573134f1b4f59df36c1b0a6de51268fd3b9c714d91f3811482263e734e416ea
@ -1800,7 +1800,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P b352f1590d20a574b0681e011ececcf4f41fa5b157503d330e03939404aca0e9
R cf317d4e595abdb01b27661d8f9d1df1
U dan
Z 1d119c13c18ffa9046c8d95a13a2ae82
P b90dbaed3092236e97f9796fa63989a3648060e16189e1267c430f4a7e799fac
R 38e7ed21c3ba7e18d21fd38b5b228c8f
U drh
Z 71c939a2336f695a4bb7bcd852576d14

View File

@ -1 +1 @@
b90dbaed3092236e97f9796fa63989a3648060e16189e1267c430f4a7e799fac
a1f6a093ac4a2de8c5b02c30fe57e09770460fd5bdddfe9c7a9a24fb83a6b491