Issues (843)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

require/libs/geoPHP/geoPHP.inc (12 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
 * (c) Patrick Hayes
4
 *
5
 * This code is open-source and licenced under the Modified BSD License.
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
// Adapters
11
include_once("lib/adapters/GeoAdapter.class.php"); // Abtract class
12
include_once("lib/adapters/GeoJSON.class.php");
13
include_once("lib/adapters/WKT.class.php");
14
include_once("lib/adapters/EWKT.class.php");
15
include_once("lib/adapters/WKB.class.php");
16
include_once("lib/adapters/EWKB.class.php");
17
include_once("lib/adapters/KML.class.php");
18
include_once("lib/adapters/GPX.class.php");
19
include_once("lib/adapters/GeoRSS.class.php");
20
include_once("lib/adapters/GoogleGeocode.class.php");
21
include_once("lib/adapters/GeoHash.class.php");
22
23
// Geometries
24
include_once("lib/geometry/Geometry.class.php"); // Abtract class
25
include_once("lib/geometry/Point.class.php");
26
include_once("lib/geometry/Collection.class.php"); // Abtract class
27
include_once("lib/geometry/LineString.class.php");
28
include_once("lib/geometry/MultiPoint.class.php");
29
include_once("lib/geometry/Polygon.class.php");
30
include_once("lib/geometry/MultiLineString.class.php");
31
include_once("lib/geometry/MultiPolygon.class.php");
32
include_once("lib/geometry/GeometryCollection.class.php");
33
34
class geoPHP
35
{
36
37
  static function version() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
38
    return '1.1';
39
  }
40
41
  // geoPHP::load($data, $type, $other_args);
42
  // if $data is an array, all passed in values will be combined into a single geometry
43
  static function load() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
44
    $args = func_get_args();
45
46
    $data = array_shift($args);
47
    $type = array_shift($args);
48
49
    $type_map = geoPHP::getAdapterMap();
50
51
    // Auto-detect type if needed
52
    if (!$type) {
53
      // If the user is trying to load a Geometry from a Geometry... Just pass it back
54
      if (is_object($data)) {
55
        if ($data instanceOf Geometry) return $data;
56
      }
57
      
58
      $detected = geoPHP::detectFormat($data);
59
      if (!$detected) {
60
        return FALSE;
61
      }
62
      
63
      $format = explode(':', $detected);
64
      $type = array_shift($format);
65
      $args = $format;
66
    }
67
68
    $processor_type = $type_map[$type];
69
70
    if (!$processor_type) {
71
      throw new exception('geoPHP could not find an adapter of type '.htmlentities($type));
72
      exit;
0 ignored issues
show
die; does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
73
    }
74
75
    $processor = new $processor_type();
76
77
    // Data is not an array, just pass it normally
78
    if (!is_array($data)) {
79
      $result = call_user_func_array(array($processor, "read"), array_merge(array($data), $args));
80
    }
81
    // Data is an array, combine all passed in items into a single geomtetry
82
    else {
83
      $geoms = array();
84
      foreach ($data as $item) {
85
        $geoms[] = call_user_func_array(array($processor, "read"), array_merge(array($item), $args));
86
      }
87
      $result = geoPHP::geometryReduce($geoms);
88
    }
89
90
    return $result;
91
  }
92
93
  static function getAdapterMap() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
94
    return array (
95
      'wkt' =>  'WKT',
96
      'ewkt' => 'EWKT',
97
      'wkb' =>  'WKB',
98
      'ewkb' => 'EWKB',
99
      'json' => 'GeoJSON',
100
      'geojson' => 'GeoJSON',
101
      'kml' =>  'KML',
102
      'gpx' =>  'GPX',
103
      'georss' => 'GeoRSS',
104
      'google_geocode' => 'GoogleGeocode',
105
      'geohash' => 'GeoHash',
106
    );
107
  }
108
109
  static function geometryList() {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
110
    return array(
111
      'point' => 'Point',
112
      'linestring' => 'LineString',
113
      'polygon' => 'Polygon',
114
      'multipoint' => 'MultiPoint',
115
      'multilinestring' => 'MultiLineString',
116
      'multipolygon' => 'MultiPolygon',
117
      'geometrycollection' => 'GeometryCollection',
118
    );
119
  }
120
121
  static function geosInstalled($force = NULL) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
122
    static $geos_installed = NULL;
123
    if ($force !== NULL) $geos_installed = $force;
124
    if ($geos_installed !== NULL) {
125
      return $geos_installed;
126
    }
127
    $geos_installed = class_exists('GEOSGeometry');
128
    return $geos_installed;
129
  }
130
131
  static function geosToGeometry($geos) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
132
    if (!geoPHP::geosInstalled()) {
133
      return NULL;
134
    }
135
    $wkb_writer = new GEOSWKBWriter();
136
    $wkb = $wkb_writer->writeHEX($geos);
137
    $geometry = geoPHP::load($wkb, 'wkb', TRUE);
138
    if ($geometry) {
139
      $geometry->setGeos($geos);
140
      return $geometry;
141
    }
142
  }
143
144
  // Reduce a geometry, or an array of geometries, into their 'lowest' available common geometry.
145
  // For example a GeometryCollection of only points will become a MultiPoint
146
  // A multi-point containing a single point will return a point.
147
  // An array of geometries can be passed and they will be compiled into a single geometry
148
  static function geometryReduce($geometry) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
149
    // If it's an array of one, then just parse the one
150
    if (is_array($geometry)) {
151
      if (empty($geometry)) return FALSE;
152
      if (count($geometry) == 1) return geoPHP::geometryReduce(array_shift($geometry));
153
    }
154
155
    // If the geometry cannot even theoretically be reduced more, then pass it back
156
    if (gettype($geometry) == 'object') {
157
      $passbacks = array('Point','LineString','Polygon');
158
      if (in_array($geometry->geometryType(),$passbacks)) {
159
        return $geometry;
160
      }
161
    }
162
163
    // If it is a mutlti-geometry, check to see if it just has one member
164
    // If it does, then pass the member, if not, then just pass back the geometry
165
    if (gettype($geometry) == 'object') {
166
      $simple_collections = array('MultiPoint','MultiLineString','MultiPolygon');
0 ignored issues
show
$simple_collections is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
167
      if (in_array(get_class($geometry),$passbacks)) {
0 ignored issues
show
The variable $passbacks does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
168
        $components = $geometry->getComponents();
169
        if (count($components) == 1) {
170
          return $components[0];
171
        }
172
        else {
173
          return $geometry;
174
        }
175
      }
176
    }
177
178
    // So now we either have an array of geometries, a GeometryCollection, or an array of GeometryCollections
179
    if (!is_array($geometry)) {
180
      $geometry = array($geometry);
181
    }
182
183
    $geometries = array();
184
    $geom_types = array();
185
186
    $collections = array('MultiPoint','MultiLineString','MultiPolygon','GeometryCollection');
187
188
    foreach ($geometry as $item) {
189
      if ($item) {
190
        if (in_array(get_class($item), $collections)) {
191
          foreach ($item->getComponents() as $component) {
192
            $geometries[] = $component;
193
            $geom_types[] = $component->geometryType();
194
          }
195
        }
196
        else {
197
          $geometries[] = $item;
198
          $geom_types[] = $item->geometryType();
199
        }
200
      }
201
    }
202
203
    $geom_types = array_unique($geom_types);
204
    
205
    if (empty($geom_types)) {
206
      return FALSE;
207
    }
208
209
    if (count($geom_types) == 1) {
210
      if (count($geometries) == 1) {
211
        return $geometries[0];
212
      }
213
      else {
214
        $class = 'Multi'.$geom_types[0];
215
        return new $class($geometries);
216
      }
217
    }
218
    else {
219
      return new GeometryCollection($geometries);
220
    }
221
  }
222
223
  // Detect a format given a value. This function is meant to be SPEEDY.
224
  // It could make a mistake in XML detection if you are mixing or using namespaces in weird ways (ie, KML inside an RSS feed)
225
  static function detectFormat(&$input) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
226
    $mem = fopen('php://memory', 'r+');
227
    fwrite($mem, $input, 11); // Write 11 bytes - we can detect the vast majority of formats in the first 11 bytes
228
    fseek($mem, 0);
229
230
    $bytes = unpack("c*", fread($mem, 11));
231
232
    // If bytes is empty, then we were passed empty input
233
    if (empty($bytes)) return FALSE;
234
235
    // First char is a tab, space or carriage-return. trim it and try again
236
    if ($bytes[1] == 9 || $bytes[1] == 10 || $bytes[1] == 32) {
237
      return geoPHP::detectFormat(ltrim($input));
0 ignored issues
show
ltrim($input) cannot be passed to detectformat() as the parameter $input expects a reference.
Loading history...
238
    }
239
240
    // Detect WKB or EWKB -- first byte is 1 (little endian indicator)
241
    if ($bytes[1] == 1) {
242
      // If SRID byte is TRUE (1), it's EWKB
243
      if ($bytes[5]) return 'ewkb';
244
      else return 'wkb';
245
    }
246
247
    // Detect HEX encoded WKB or EWKB (PostGIS format) -- first byte is 48, second byte is 49 (hex '01' => first-byte = 1)
248
    if ($bytes[1] == 48 && $bytes[2] == 49) {
249
      // The shortest possible WKB string (LINESTRING EMPTY) is 18 hex-chars (9 encoded bytes) long
250
      // This differentiates it from a geohash, which is always shorter than 18 characters.
251
      if (strlen($input) >= 18) {
252
        //@@TODO: Differentiate between EWKB and WKB -- check hex-char 10 or 11 (SRID bool indicator at encoded byte 5)
253
        return 'ewkb:1';
254
      }
255
    }
256
257
    // Detect GeoJSON - first char starts with {
258
    if ($bytes[1] == 123) {
259
      return 'json';
260
    }
261
262
    // Detect EWKT - first char is S
263
    if ($bytes[1] == 83) {
264
      return 'ewkt';
265
    }
266
267
    // Detect WKT - first char starts with P (80), L (76), M (77), or G (71)
268
    $wkt_chars = array(80, 76, 77, 71);
269
    if (in_array($bytes[1], $wkt_chars)) {
270
      return 'wkt';
271
    }
272
273
    // Detect XML -- first char is <
274
    if ($bytes[1] == 60) {
275
      // grab the first 256 characters
276
      $string = substr($input, 0, 256);
277
      if (strpos($string, '<kml') !== FALSE)        return 'kml';
278
      if (strpos($string, '<coordinate') !== FALSE) return 'kml';
279
      if (strpos($string, '<gpx') !== FALSE)        return 'gpx';
280
      if (strpos($string, '<georss') !== FALSE)     return 'georss';
281
      if (strpos($string, '<rss') !== FALSE)        return 'georss';
282
      if (strpos($string, '<feed') !== FALSE)       return 'georss';
283
    }
284
285
    // We need an 8 byte string for geohash and unpacked WKB / WKT
286
    fseek($mem, 0);
287
    $string = trim(fread($mem, 8));
288
289
    // Detect geohash - geohash ONLY contains lowercase chars and numerics
290
    preg_match('/[a-z0-9]+/', $string, $matches);
291
    if ($matches[0] == $string) {
292
      return 'geohash';
293
    }
294
295
    // What do you get when you cross an elephant with a rhino?
296
    // http://youtu.be/RCBn5J83Poc
297
    return FALSE;
298
  }
299
300
}
301