diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c2fc6e..a153b50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Note: you may refer to `README.md` for description of features. ## Dev (WIP) +Fixed decoding of OLC producing out-of-bounds coordinates (https://github.com/Vectorial1024/open-location-code-php/pull/6). + ## 1.1.3 (2026-04-21) GitHub security advisory (https://github.com/advisories/GHSA-qrr6-mg7r-m243) diff --git a/src/CodeCalculator/CodeCalculatorFloat.php b/src/CodeCalculator/CodeCalculatorFloat.php index e811568..5640956 100644 --- a/src/CodeCalculator/CodeCalculatorFloat.php +++ b/src/CodeCalculator/CodeCalculatorFloat.php @@ -81,7 +81,7 @@ protected function generateCodeArea(string $strippedCode): CodeArea // Define the place value for the digits. We'll divide this down as we work through the code. $latPlaceVal = self::LAT_MSP_VALUE; $lngPlaceVal = self::LNG_MSP_VALUE; - for ($i = OpenLocationCode::PAIR_CODE_LENGTH; $i < min(strlen($strippedCode), OpenLocationCode::MAX_DIGIT_COUNT); $i += 2) { + for ($i = 0; $i < min(strlen($strippedCode), OpenLocationCode::MAX_DIGIT_COUNT); $i += 2) { $latPlaceVal = floor($latPlaceVal / OpenLocationCode::ENCODING_BASE); $lngPlaceVal = floor($lngPlaceVal / OpenLocationCode::ENCODING_BASE); $latVal += strpos(OpenLocationCode::CODE_ALPHABET, $strippedCode[$i]) * $latPlaceVal; diff --git a/src/CodeCalculator/CodeCalculatorInt.php b/src/CodeCalculator/CodeCalculatorInt.php index 87f2294..7c2d363 100644 --- a/src/CodeCalculator/CodeCalculatorInt.php +++ b/src/CodeCalculator/CodeCalculatorInt.php @@ -83,11 +83,11 @@ protected function generateCodeArea(string $strippedCode): CodeArea // Define the place value for the digits. We'll divide this down as we work through the code. $latPlaceVal = self::LAT_MSP_VALUE; $lngPlaceVal = self::LNG_MSP_VALUE; - for ($i = OpenLocationCode::PAIR_CODE_LENGTH; $i < min(strlen($strippedCode), OpenLocationCode::MAX_DIGIT_COUNT); $i += 2) { + for ($i = 0; $i < min(strlen($strippedCode), OpenLocationCode::MAX_DIGIT_COUNT); $i += 2) { $latPlaceVal = intdiv($latPlaceVal, OpenLocationCode::ENCODING_BASE); $lngPlaceVal = intdiv($lngPlaceVal, OpenLocationCode::ENCODING_BASE); $latVal += strpos(OpenLocationCode::CODE_ALPHABET, $strippedCode[$i]) * $latPlaceVal; - $lngVal = strpos(OpenLocationCode::CODE_ALPHABET, $strippedCode[$i + 1]) * $lngPlaceVal; + $lngVal += strpos(OpenLocationCode::CODE_ALPHABET, $strippedCode[$i + 1]) * $lngPlaceVal; } unset($i); for ($i = OpenLocationCode::PAIR_CODE_LENGTH; $i < min(strlen($strippedCode), OpenLocationCode::MAX_DIGIT_COUNT); $i++) { diff --git a/test/OpenLocationCodeTest.php b/test/OpenLocationCodeTest.php index ffa14ed..77ddd31 100644 --- a/test/OpenLocationCodeTest.php +++ b/test/OpenLocationCodeTest.php @@ -46,6 +46,8 @@ public function testCorrectCodeFromCoordinates(float $latitude, float $longitude $resultCode = $floatCal->encode($latitude, $longitude, OpenLocationCode::CODE_PRECISION_NORMAL); $this->assertEquals($resultCode, $expectedCode); $resultCodeArea = $floatCal->decode($expectedCode); + $this->confirmCoordinatesValidity($resultCodeArea->northLatitude, $resultCodeArea->eastLongitude); + $this->confirmCoordinatesValidity($resultCodeArea->southLatitude, $resultCodeArea->westLongitude); $this->assertTrue($resultCodeArea->contains($latitude, $longitude)); if (PHP_INT_SIZE >= 8) { // at least 64-bit, which means we can use "long" ints here @@ -57,6 +59,16 @@ public function testCorrectCodeFromCoordinates(float $latitude, float $longitude } } + private function confirmCoordinatesValidity(float $latitude, float $longitude): void + { + // check latitude + $this->assertGreaterThanOrEqual(-90, $latitude); + $this->assertLessThanOrEqual(90, $latitude); + // check longitude + $this->assertGreaterThanOrEqual(-180, $longitude); + $this->assertLessThanOrEqual(180, $longitude); + } + public static function codeValidityProvider(): array { return [ @@ -76,7 +88,7 @@ public static function encodingProvider(): array "Changi Airport, Singapore" => [1.357063, 103.988563, "6PH59X4Q+RC"], "International Antarctic Centre, Christchurch" => [-43.489063, 172.547188, "4V8JGG6W+9V"], "Christo Redentor, Rio de Janeiro" => [-22.951937, -43.210437, "589R2QXQ+6R"], - "New Chitose Airport, Chitose" => [42.786062,141.680937, "8RJ3QMPJ+C9"], + "New Chitose Airport, Chitose" => [42.786062, 141.680937, "8RJ3QMPJ+C9"], "Berling Strait" => [65.759937, -169.149437, "92QGQV52+X6"], "Null point" => [0, 0, "6FG22222+22"], ];