When installing an app from the appstore the `\OC_App::getAppVersion` code is triggered twice: - First when the downloader tries to compare the current version to the new version on the appstore to check if there is a newer version. This protects against downgrade attacks and is implemented in `\OC\Installer::downloadApp`. - Second, when the app is actually installed the current version is written to the database. (`\OC\Installer::installApp`) This fails however when the version is actually cached. Because in step 1 the cached version will be set to "0" and then be reused in the second step. While this is probably not the cleanest version I assume this is an approach that is least invasive. Feedback and suggestions welcome :) Signed-off-by: Lukas Reschke <lukas@statuscode.ch>tags/v11.0RC2
@@ -121,7 +121,7 @@ class Installer { | |||
OC_App::executeRepairSteps($appId, $appData['repair-steps']['install']); | |||
//set the installed version | |||
\OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id'])); | |||
\OC::$server->getConfig()->setAppValue($info['id'], 'installed_version', OC_App::getAppVersion($info['id'], false)); | |||
\OC::$server->getConfig()->setAppValue($info['id'], 'enabled', 'no'); | |||
//set remote/public handlers |
@@ -653,13 +653,16 @@ class OC_App { | |||
* get the last version of the app from appinfo/info.xml | |||
* | |||
* @param string $appId | |||
* @param bool $useCache | |||
* @return string | |||
*/ | |||
public static function getAppVersion($appId) { | |||
if (!isset(self::$appVersion[$appId])) { | |||
$file = self::getAppPath($appId); | |||
self::$appVersion[$appId] = ($file !== false) ? self::getAppVersionByPath($file) : '0'; | |||
public static function getAppVersion($appId, $useCache = true) { | |||
if($useCache && isset(self::$appVersion[$appId])) { | |||
return self::$appVersion[$appId]; | |||
} | |||
$file = self::getAppPath($appId); | |||
self::$appVersion[$appId] = ($file !== false) ? self::getAppVersionByPath($file) : '0'; | |||
return self::$appVersion[$appId]; | |||
} | |||
@@ -73,6 +73,9 @@ class InstallerTest extends TestCase { | |||
} | |||
public function testInstallApp() { | |||
// Read the current version of the app to check for bug #2572 | |||
\OC_App::getAppVersion('testapp'); | |||
// Extract app | |||
$pathOfTestApp = __DIR__ . '/../data/testapp.zip'; | |||
$tar = new ZIP($pathOfTestApp); | |||
@@ -88,6 +91,7 @@ class InstallerTest extends TestCase { | |||
$installer->installApp(self::$appid); | |||
$isInstalled = Installer::isInstalled(self::$appid); | |||
$this->assertTrue($isInstalled); | |||
$this->assertSame('0.9', \OC::$server->getConfig()->getAppValue('testapp', 'installed_version')); | |||
$installer->removeApp(self::$appid); | |||
} | |||