json_decode: always throw on error and fix other psalm issues

Signed-off-by: Simon L. <szaimen@e.mail.de>
This commit is contained in:
Simon L. 2025-11-05 12:33:07 +01:00
parent df0f7b8d85
commit 6f945a2369
6 changed files with 19 additions and 23 deletions

View file

@ -1,10 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="6.13.1@1e3b7f0a8ab32b23197b91107adc0a7ed8a05b51"> <files psalm-version="6.13.1@1e3b7f0a8ab32b23197b91107adc0a7ed8a05b51">
<file src="src/ContainerDefinitionFetcher.php">
<PossiblyFalseArgument>
<code><![CDATA[file_get_contents($path)]]></code>
</PossiblyFalseArgument>
</file>
<file src="src/Controller/DockerController.php"> <file src="src/Controller/DockerController.php">
<InvalidOperand> <InvalidOperand>
<code><![CDATA[$port]]></code> <code><![CDATA[$port]]></code>
@ -29,7 +24,6 @@
<code><![CDATA[$content]]></code> <code><![CDATA[$content]]></code>
<code><![CDATA[$dailyBackupFile]]></code> <code><![CDATA[$dailyBackupFile]]></code>
<code><![CDATA[$dailyBackupFile]]></code> <code><![CDATA[$dailyBackupFile]]></code>
<code><![CDATA[file_get_contents(DataConst::GetBackupPublicKey())]]></code>
</PossiblyFalseArgument> </PossiblyFalseArgument>
</file> </file>
<file src="src/Docker/DockerActionManager.php"> <file src="src/Docker/DockerActionManager.php">

View file

@ -38,13 +38,13 @@ readonly class ContainerDefinitionFetcher {
*/ */
private function GetDefinition(): array private function GetDefinition(): array
{ {
$data = json_decode(file_get_contents(DataConst::GetContainersDefinitionPath()), true); $data = json_decode((string)file_get_contents(DataConst::GetContainersDefinitionPath()), true, 512, JSON_THROW_ON_ERROR);
$additionalContainerNames = []; $additionalContainerNames = [];
foreach ($this->configurationManager->GetEnabledCommunityContainers() as $communityContainer) { foreach ($this->configurationManager->GetEnabledCommunityContainers() as $communityContainer) {
if ($communityContainer !== '') { if ($communityContainer !== '') {
$path = DataConst::GetCommunityContainersDirectory() . '/' . $communityContainer . '/' . $communityContainer . '.json'; $path = DataConst::GetCommunityContainersDirectory() . '/' . $communityContainer . '/' . $communityContainer . '.json';
$additionalData = json_decode(file_get_contents($path), true); $additionalData = json_decode((string)file_get_contents($path), true, 512, JSON_THROW_ON_ERROR);
$data = array_merge_recursive($data, $additionalData); $data = array_merge_recursive($data, $additionalData);
if (isset($additionalData['aio_services_v1'][0]['display_name']) && $additionalData['aio_services_v1'][0]['display_name'] !== '') { if (isset($additionalData['aio_services_v1'][0]['display_name']) && $additionalData['aio_services_v1'][0]['display_name'] !== '') {
// Store container_name of community containers in variable for later // Store container_name of community containers in variable for later

View file

@ -636,7 +636,7 @@ class ConfigurationManager
return ""; return "";
} }
return trim(file_get_contents(DataConst::GetBackupPublicKey())); return trim((string)file_get_contents(DataConst::GetBackupPublicKey()));
} }
public function GetBorgRestorePassword() : string { public function GetBorgRestorePassword() : string {
@ -1040,7 +1040,7 @@ class ConfigurationManager
apcu_add($filePath, $fileContents); apcu_add($filePath, $fileContents);
} }
} }
$json = is_string($fileContents) ? json_decode($fileContents, true) : false; $json = is_string($fileContents) ? json_decode($fileContents, true, 512, JSON_THROW_ON_ERROR) : false;
if(is_array($json) && is_array($json['aio_services_v1'])) { if(is_array($json) && is_array($json['aio_services_v1'])) {
foreach ($json['aio_services_v1'] as $service) { foreach ($json['aio_services_v1'] as $service) {
$documentation = is_string($service['documentation']) ? $service['documentation'] : ''; $documentation = is_string($service['documentation']) ? $service['documentation'] : '';

View file

@ -48,7 +48,7 @@ readonly class DockerActionManager {
throw $e; throw $e;
} }
$responseBody = json_decode((string)$response->getBody(), true); $responseBody = json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
if ($responseBody['State']['Running'] === true) { if ($responseBody['State']['Running'] === true) {
return ContainerState::Running; return ContainerState::Running;
@ -68,7 +68,7 @@ readonly class DockerActionManager {
throw $e; throw $e;
} }
$responseBody = json_decode((string)$response->getBody(), true); $responseBody = json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
if ($responseBody['State']['Restarting'] === true) { if ($responseBody['State']['Restarting'] === true) {
return ContainerState::Restarting; return ContainerState::Restarting;
@ -405,7 +405,7 @@ readonly class DockerActionManager {
// Special things for the collabora container which should not be exposed in the containers.json // Special things for the collabora container which should not be exposed in the containers.json
} elseif ($container->GetIdentifier() === 'nextcloud-aio-collabora') { } elseif ($container->GetIdentifier() === 'nextcloud-aio-collabora') {
// Load reference seccomp profile for collabora // Load reference seccomp profile for collabora
$seccompProfile = file_get_contents(DataConst::GetCollaboraSeccompProfilePath()); $seccompProfile = (string)file_get_contents(DataConst::GetCollaboraSeccompProfilePath());
$seccompProfile = addslashes($seccompProfile); $seccompProfile = addslashes($seccompProfile);
$requestBody['HostConfig']['SecurityOpt'] = ["label:disable", "seccomp=$seccompProfile", "no-new-privileges=true", "apparmor=unconfined"]; $requestBody['HostConfig']['SecurityOpt'] = ["label:disable", "seccomp=$seccompProfile", "no-new-privileges=true", "apparmor=unconfined"];
@ -643,11 +643,11 @@ readonly class DockerActionManager {
private function GetRepoDigestsOfContainer(string $containerName): ?array { private function GetRepoDigestsOfContainer(string $containerName): ?array {
try { try {
$containerUrl = $this->BuildApiUrl(sprintf('containers/%s/json', $containerName)); $containerUrl = $this->BuildApiUrl(sprintf('containers/%s/json', $containerName));
$containerOutput = json_decode($this->guzzleClient->get($containerUrl)->getBody()->getContents(), true); $containerOutput = json_decode($this->guzzleClient->get($containerUrl)->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
$imageName = $containerOutput['Image']; $imageName = $containerOutput['Image'];
$imageUrl = $this->BuildApiUrl(sprintf('images/%s/json', $imageName)); $imageUrl = $this->BuildApiUrl(sprintf('images/%s/json', $imageName));
$imageOutput = json_decode($this->guzzleClient->get($imageUrl)->getBody()->getContents(), true); $imageOutput = json_decode($this->guzzleClient->get($imageUrl)->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
if (!isset($imageOutput['RepoDigests'])) { if (!isset($imageOutput['RepoDigests'])) {
error_log('RepoDigests is not set of container ' . $containerName); error_log('RepoDigests is not set of container ' . $containerName);
@ -691,7 +691,7 @@ readonly class DockerActionManager {
$containerName = 'nextcloud-aio-mastercontainer'; $containerName = 'nextcloud-aio-mastercontainer';
$url = $this->BuildApiUrl(sprintf('containers/%s/json', $containerName)); $url = $this->BuildApiUrl(sprintf('containers/%s/json', $containerName));
try { try {
$output = json_decode($this->guzzleClient->get($url)->getBody()->getContents(), true); $output = json_decode($this->guzzleClient->get($url)->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
$imageNameArray = explode(':', $output['Config']['Image']); $imageNameArray = explode(':', $output['Config']['Image']);
if (count($imageNameArray) === 2) { if (count($imageNameArray) === 2) {
$imageName = $imageNameArray[0]; $imageName = $imageNameArray[0];
@ -718,7 +718,7 @@ readonly class DockerActionManager {
$containerName = 'nextcloud-aio-mastercontainer'; $containerName = 'nextcloud-aio-mastercontainer';
$url = $this->BuildApiUrl(sprintf('containers/%s/json', $containerName)); $url = $this->BuildApiUrl(sprintf('containers/%s/json', $containerName));
try { try {
$output = json_decode($this->guzzleClient->get($url)->getBody()->getContents(), true); $output = json_decode($this->guzzleClient->get($url)->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
$tagArray = explode(':', $output['Config']['Image']); $tagArray = explode(':', $output['Config']['Image']);
if (count($tagArray) === 2) { if (count($tagArray) === 2) {
$tag = $tagArray[1]; $tag = $tagArray[1];
@ -782,7 +782,9 @@ readonly class DockerActionManager {
], ],
] ]
)->getBody()->getContents(), )->getBody()->getContents(),
true true,
512,
JSON_THROW_ON_ERROR,
); );
$id = $response['Id']; $id = $response['Id'];
@ -924,7 +926,7 @@ readonly class DockerActionManager {
throw $e; throw $e;
} }
$responseBody = json_decode((string)$response->getBody(), true); $responseBody = json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
$exitCode = $responseBody['State']['ExitCode']; $exitCode = $responseBody['State']['ExitCode'];
if (is_int($exitCode)) { if (is_int($exitCode)) {
@ -946,7 +948,7 @@ readonly class DockerActionManager {
throw $e; throw $e;
} }
$responseBody = json_decode((string)$response->getBody(), true); $responseBody = json_decode((string)$response->getBody(), true, 512, JSON_THROW_ON_ERROR);
$exitCode = $responseBody['State']['ExitCode']; $exitCode = $responseBody['State']['ExitCode'];
if (is_int($exitCode)) { if (is_int($exitCode)) {
@ -978,7 +980,7 @@ readonly class DockerActionManager {
$imageName = $imageName . ':' . $this->GetCurrentChannel(); $imageName = $imageName . ':' . $this->GetCurrentChannel();
try { try {
$imageUrl = $this->BuildApiUrl(sprintf('images/%s/json', $imageName)); $imageUrl = $this->BuildApiUrl(sprintf('images/%s/json', $imageName));
$imageOutput = json_decode($this->guzzleClient->get($imageUrl)->getBody()->getContents(), true); $imageOutput = json_decode($this->guzzleClient->get($imageUrl)->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
if (!isset($imageOutput['Created'])) { if (!isset($imageOutput['Created'])) {
error_log('Created is not set of image ' . $imageName); error_log('Created is not set of image ' . $imageName);

View file

@ -30,7 +30,7 @@ readonly class DockerHubManager {
'https://auth.docker.io/token?service=registry.docker.io&scope=repository:' . $name . ':pull' 'https://auth.docker.io/token?service=registry.docker.io&scope=repository:' . $name . ':pull'
); );
$body = $authTokenRequest->getBody()->getContents(); $body = $authTokenRequest->getBody()->getContents();
$decodedBody = json_decode($body, true); $decodedBody = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if(isset($decodedBody['token'])) { if(isset($decodedBody['token'])) {
$authToken = $decodedBody['token']; $authToken = $decodedBody['token'];
$manifestRequest = $this->guzzleClient->request( $manifestRequest = $this->guzzleClient->request(

View file

@ -31,7 +31,7 @@ readonly class GitHubContainerRegistryManager
'https://ghcr.io/token?scope=repository:' . $name . ':pull' 'https://ghcr.io/token?scope=repository:' . $name . ':pull'
); );
$body = $authTokenRequest->getBody()->getContents(); $body = $authTokenRequest->getBody()->getContents();
$decodedBody = json_decode($body, true); $decodedBody = json_decode($body, true, 512, JSON_THROW_ON_ERROR);
if (isset($decodedBody['token'])) { if (isset($decodedBody['token'])) {
$authToken = $decodedBody['token']; $authToken = $decodedBody['token'];
$manifestRequest = $this->guzzleClient->request( $manifestRequest = $this->guzzleClient->request(