Skip to content

Commit

Permalink
fix(FDroidRepoBridge): unlink when json file is absent from archive
Browse files Browse the repository at this point in the history
  • Loading branch information
dvikan committed Apr 4, 2024
1 parent 82606a4 commit 8808db9
Showing 1 changed file with 59 additions and 51 deletions.
110 changes: 59 additions & 51 deletions bridges/FDroidRepoBridge.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function collectData()
throw new \Exception('FDroidRepoBridge requires the php-zip extension');
}

$this->repo = $this->getRepo();
$this->repo = $this->fetchData();
switch ($this->queriedContext) {
case 'Latest Updates':
$this->getAllUpdates();
Expand All @@ -58,63 +58,40 @@ public function collectData()
$this->getPackage($this->getInput('package'));
break;
default:
returnServerError('Unimplemented Context (collectData)');
throw new \Exception('Unimplemented Context (collectData)');
}
}

public function getURI()
{
if (empty($this->queriedContext)) {
return parent::getURI();
}

$url = rtrim($this->GetInput('url'), '/');
return strstr($url, '?', true) ?: $url;
}

public function getName()
{
if (empty($this->queriedContext)) {
return parent::getName();
}

$name = $this->repo['repo']['name'];
switch ($this->queriedContext) {
case 'Latest Updates':
return $name;
case 'Follow Package':
return $this->getInput('package') . ' - ' . $name;
default:
returnServerError('Unimplemented Context (getName)');
}
}

private function getRepo()
/**
* This method fetches data from arbitrary url and writes to os temp file.
* I don't think there's any security problem here but might be DOS problems.
*/
private function fetchData()
{
$url = $this->getURI();

// Get repo information (only available as JAR)
$jar = getContents($url . '/index-v1.jar');
$jar_loc = tempnam(sys_get_temp_dir(), '');
file_put_contents($jar_loc, $jar);
$zipFile = getContents($url . '/index-v1.jar');
// On linux this creates a temp file in /tmp/
$temporaryFile = tempnam(sys_get_temp_dir(), 'rssbridge_');
file_put_contents($temporaryFile, $zipFile);

// JAR files are specially formatted ZIP files
$jar = new \ZipArchive();
if ($jar->open($jar_loc) !== true) {
unlink($jar_loc);
$archive = new \ZipArchive();
if ($archive->open($temporaryFile) !== true) {
unlink($temporaryFile);
throw new \Exception('Failed to extract archive');
}

// Get file pointer to the relevant JSON inside
$fp = $jar->getStream('index-v1.json');
$fp = $archive->getStream('index-v1.json');
if (!$fp) {
returnServerError('Failed to get file pointer');
unlink($temporaryFile);
throw new \Exception('Failed to get file pointer');
}

$data = json_decode(stream_get_contents($fp), true);
$json = stream_get_contents($fp);
fclose($fp);
$jar->close();
unlink($jar_loc);
$data = Json::decode($json);
$archive->close();
unlink($temporaryFile);
return $data;
}

Expand Down Expand Up @@ -158,9 +135,9 @@ private function getAllUpdates()
$summary = $lang['summary'] ?? $app['summary'] ?? '';
$description = markdownToHtml(trim($lang['description'] ?? $app['description'] ?? 'None'));
$whatsNew = markdownToHtml(trim($lang['whatsNew'] ?? 'None'));
$website = $this->link($lang['webSite'] ?? $app['webSite'] ?? $app['authorWebSite'] ?? null);
$source = $this->link($app['sourceCode'] ?? null);
$issueTracker = $this->link($app['issueTracker'] ?? null);
$website = $this->createAnchor($lang['webSite'] ?? $app['webSite'] ?? $app['authorWebSite'] ?? null);
$source = $this->createAnchor($app['sourceCode'] ?? null);
$issueTracker = $this->createAnchor($app['issueTracker'] ?? null);
$license = $app['license'] ?? 'None';
$item['content'] = <<<EOD
{$icon}
Expand All @@ -182,7 +159,7 @@ private function getAllUpdates()
private function getPackage($package)
{
if (!isset($this->repo['packages'][$package])) {
returnClientError('Invalid Package Name');
throw new \Exception('Invalid Package Name');
}
$package = $this->repo['packages'][$package];

Expand All @@ -192,7 +169,7 @@ private function getPackage($package)
$item['uri'] = $this->getURI() . '/' . $version['apkName'];
$item['title'] = $version['versionName'];
$item['timestamp'] = date(DateTime::ISO8601, (int) ($version['added'] / 1000));
$item['uid'] = $version['versionCode'];
$item['uid'] = (string) $version['versionCode'];
$size = round($version['size'] / 1048576, 1); // Bytes -> MB
$sdk_link = 'https://developer.android.com/studio/releases/platforms';
$item['content'] = <<<EOD
Expand All @@ -208,11 +185,42 @@ private function getPackage($package)
}
}

private function link($url)
public function getURI()
{
if (empty($this->queriedContext)) {
return parent::getURI();
}

$url = rtrim($this->getInput('url'), '/');
if (strstr($url, '?', true)) {
return strstr($url, '?', true);
} else {
return $url;
}
}

public function getName()
{
if (empty($this->queriedContext)) {
return parent::getName();
}

$name = $this->repo['repo']['name'];
switch ($this->queriedContext) {
case 'Latest Updates':
return $name;
case 'Follow Package':
return $this->getInput('package') . ' - ' . $name;
default:
throw new \Exception('Unimplemented Context (getName)');
}
}

private function createAnchor($url)
{
if (empty($url)) {
return null;
}
return '<a href="' . $url . '">' . $url . '</a>';
return sprintf('<a href="%s">%s</a>', $url, $url);
}
}

0 comments on commit 8808db9

Please sign in to comment.