From ea9ee985e85b0093ac5b14858b74c93883884024 Mon Sep 17 00:00:00 2001 From: Nabeel S Date: Fri, 28 Feb 2020 22:50:41 -0500 Subject: [PATCH] METAR parsing infinite loop bugfix #599 (#600) METAR parsing infinite loop bugfix #599 --- app/Services/Metar/AviationWeather.php | 24 +++++++++++++++++++++--- app/Widgets/Weather.php | 1 + tests/MetarTest.php | 11 +++++++++++ tests/data/aviationweather/unknown.xml | 0 4 files changed, 33 insertions(+), 3 deletions(-) create mode 100644 tests/data/aviationweather/unknown.xml diff --git a/app/Services/Metar/AviationWeather.php b/app/Services/Metar/AviationWeather.php index 8c894272..400ce1b3 100644 --- a/app/Services/Metar/AviationWeather.php +++ b/app/Services/Metar/AviationWeather.php @@ -4,6 +4,8 @@ namespace App\Services\Metar; use App\Contracts\Metar; use App\Support\HttpClient; +use function count; +use Exception; use Illuminate\Support\Facades\Log; /** @@ -44,15 +46,31 @@ class AviationWeather extends Metar try { $res = $this->httpClient->get($url, []); $xml = simplexml_load_string($res); - if (\count($xml->data->METAR->raw_text) === 0) { + + $attrs = $xml->data->attributes(); + if (!isset($attrs['num_results'])) { + return ''; + } + + $num_results = $attrs['num_results']; + if (empty($num_results)) { + return ''; + } + + $num_results = (int) $num_results; + if ($num_results === 0) { + return ''; + } + + if (count($xml->data->METAR->raw_text) === 0) { return ''; } return $xml->data->METAR->raw_text->__toString(); - } catch (\Exception $e) { + } catch (Exception $e) { Log::error('Error reading METAR: '.$e->getMessage()); - throw $e; + return ''; } } } diff --git a/app/Widgets/Weather.php b/app/Widgets/Weather.php index 1cf6491d..194e356e 100644 --- a/app/Widgets/Weather.php +++ b/app/Widgets/Weather.php @@ -19,6 +19,7 @@ class Weather extends Widget */ public function run() { + /** @var \App\Services\AirportService $airportSvc */ $airportSvc = app(AirportService::class); $metar = $airportSvc->getMetar($this->config['icao']); diff --git a/tests/MetarTest.php b/tests/MetarTest.php index c0472ea0..82f577a5 100644 --- a/tests/MetarTest.php +++ b/tests/MetarTest.php @@ -185,4 +185,15 @@ class MetarTest extends TestCase $this->assertNull($airportSvc->getMetar('idk')); } + + public function testHttpCallUnknown() + { + $this->mockXmlResponse('aviationweather/unknown.xml'); + + /** @var AirportService $airportSvc */ + $airportSvc = app(AirportService::class); + + $metar = $airportSvc->getMetar('7AK4'); + $this->assertNull($metar); + } } diff --git a/tests/data/aviationweather/unknown.xml b/tests/data/aviationweather/unknown.xml new file mode 100644 index 00000000..e69de29b