SQLite

Check-in [c0bf3ff3af]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Stricter enforcement of the JSON and GeoJSON standards in the Geopoly extension.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: c0bf3ff3af4d34ef7801c16e39128e894b00699313f4915f57aa73b57642f7fd
User & Date: drh 2018-08-28 19:23:41.917
Context
2018-08-28
21:12
Disable the server1.test script on old PPC Macs due to problems in the pthreads implementation on those archaic machines. (check-in: 43efdd8c7e user: drh tags: trunk)
19:23
Stricter enforcement of the JSON and GeoJSON standards in the Geopoly extension. (check-in: c0bf3ff3af user: drh tags: trunk)
15:51
Fix new issues in the geopoly module discovered by TH3. (check-in: 22fff9afc2 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to ext/rtree/geopoly.c.
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

160
161
162
163
164
165
166

/* Parse out a number.  Write the value into *pVal if pVal!=0.
** return non-zero on success and zero if the next token is not a number.
*/
static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
  char c = geopolySkipSpace(p);
  const unsigned char *z = p->z;
  int j;
  int seenDP = 0;
  int seenE = 0;
  assert( '-' < '0' );
  if( c<='0' ){
    j = c=='-';
    if( z[j]=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
  }
  j = 1;

  for(;; j++){
    c = z[j];
    if( c>='0' && c<='9' ) continue;
    if( c=='.' ){
      if( z[j-1]=='-' ) return 0;
      if( seenDP ) return 0;
      seenDP = 1;







|


<
|
|
|

<
>







144
145
146
147
148
149
150
151
152
153

154
155
156
157

158
159
160
161
162
163
164
165

/* Parse out a number.  Write the value into *pVal if pVal!=0.
** return non-zero on success and zero if the next token is not a number.
*/
static int geopolyParseNumber(GeoParse *p, GeoCoord *pVal){
  char c = geopolySkipSpace(p);
  const unsigned char *z = p->z;
  int j = 0;
  int seenDP = 0;
  int seenE = 0;

  if( c=='-' ){
    j = 1;
    c = z[j];
  }

  if( c=='0' && z[j+1]>='0' && z[j+1]<='9' ) return 0;
  for(;; j++){
    c = z[j];
    if( c>='0' && c<='9' ) continue;
    if( c=='.' ){
      if( z[j-1]=='-' ) return 0;
      if( seenDP ) return 0;
      seenDP = 1;
231
232
233
234
235
236
237


238
239
240
241
242
243
244
245
246
247
248
249
250
251
        s.z++;
        continue;
      }
      break;
    }
    if( geopolySkipSpace(&s)==']'
     && s.nVertex>=4


     && (s.z++, geopolySkipSpace(&s)==0)
    ){
      int nByte;
      GeoPoly *pOut;
      int x = (s.nVertex-1)*2;
      if( s.a[x]==s.a[0] && s.a[x+1]==s.a[1] ) s.nVertex--;
      nByte = sizeof(GeoPoly) * (s.nVertex-1)*2*sizeof(GeoCoord);
      pOut = sqlite3_malloc64( nByte );
      x = 1;
      if( pOut==0 ) goto parse_json_err;
      pOut->nVertex = s.nVertex;
      memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
      pOut->hdr[0] = *(unsigned char*)&x;
      pOut->hdr[1] = (s.nVertex>>16)&0xff;







>
>




|
|
|







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
        s.z++;
        continue;
      }
      break;
    }
    if( geopolySkipSpace(&s)==']'
     && s.nVertex>=4
     && s.a[0]==s.a[s.nVertex*2-2]
     && s.a[1]==s.a[s.nVertex*2-1]
     && (s.z++, geopolySkipSpace(&s)==0)
    ){
      int nByte;
      GeoPoly *pOut;
      int x = 1;
      s.nVertex--;  /* Remove the redundant vertex at the end */
      nByte = sizeof(GeoPoly) * s.nVertex*2*sizeof(GeoCoord);
      pOut = sqlite3_malloc64( nByte );
      x = 1;
      if( pOut==0 ) goto parse_json_err;
      pOut->nVertex = s.nVertex;
      memcpy(pOut->a, s.a, s.nVertex*2*sizeof(GeoCoord));
      pOut->hdr[0] = *(unsigned char*)&x;
      pOut->hdr[1] = (s.nVertex>>16)&0xff;
303
304
305
306
307
308
309





310
311
312
313
314
315
316
317
318
319
320
          p->hdr[0] ^= 1;
        }
      }
    }
    if( pRc ) *pRc = SQLITE_OK;
    return p;
  }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){





    return geopolyParseJson(sqlite3_value_text(pVal), pRc);
  }else{
    if( pRc ) *pRc = SQLITE_ERROR;
    if( pCtx!=0 ) sqlite3_result_error(pCtx, "not a valid polygon", -1);
    return 0;
  }
}

/*
** Implementation of the geopoly_blob(X) function.
**







>
>
>
>
>
|


<







304
305
306
307
308
309
310
311
312
313
314
315
316
317
318

319
320
321
322
323
324
325
          p->hdr[0] ^= 1;
        }
      }
    }
    if( pRc ) *pRc = SQLITE_OK;
    return p;
  }else if( sqlite3_value_type(pVal)==SQLITE_TEXT ){
    const unsigned char *zJson = sqlite3_value_text(pVal);
    if( zJson==0 ){
      if( pRc ) *pRc = SQLITE_NOMEM;
      return 0;
    }
    return geopolyParseJson(zJson, pRc);
  }else{
    if( pRc ) *pRc = SQLITE_ERROR;

    return 0;
  }
}

/*
** Implementation of the geopoly_blob(X) function.
**