Completed
Pull Request — master (#217)
by Thomas
02:42
created

DownloadController::checkIntegrity()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 9
ccs 8
cts 8
cp 1
rs 9.6666
cc 3
eloc 7
nc 2
nop 2
crap 3
1
<?php
2
/**
3
 * @author Victor Dubiniuk <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2015, ownCloud, Inc.
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace Owncloud\Updater\Controller;
23
24
use Owncloud\Updater\Utils\Fetcher;
25
use Owncloud\Updater\Utils\Registry;
26
use Owncloud\Updater\Utils\FilesystemHelper;
27
28
class DownloadController {
29
	
30
	/**
31
	 * @var Fetcher 
32
	 */
33
	protected $fetcher;
34
35
	/**
36
	 * @var Registry
37
	 */
38
	protected $registry;
39
40
	/**
41
	 * @var FilesystemHelper
42
	 */
43
	protected $fsHelper;
44
45 4
	public function __construct(Fetcher $fetcher, Registry $registry, FilesystemHelper $fsHelper){
46 4
		$this->fetcher = $fetcher;
47 4
		$this->registry = $registry;
48 4
		$this->fsHelper = $fsHelper;
49 4
	}
50
51 2
	public function checkFeed(){
52 2
		$response = $this->getDefaultResponse();
53
		try {
54 2
			$feed = $this->fetcher->getFeed();
55 1
			if ($feed->isValid()){
56 1
				$response['success'] = true;
57 1
				$response['data']['feed'] = $feed;
58 1
			}
59 2
		} catch (\Exception $e){
60 1
			$response['exception'] = $e;
61
		}
62
63 2
		return $response;
64
	}
65
66 2
	public function downloadOwncloud($progressCallback = null){
67 2
		$response = $this->getDefaultResponse();
68 2
		if (is_null($progressCallback)){
69
			$progressCallback = function (){};
70 2
		}
71
		try {
72 2
			$feed = $this->getFeed();
73 2
			$path = $this->fetcher->getBaseDownloadPath($feed);
74
			// Fixme: Daily channel has no checksum
75 2
			$isDailyChannel = $this->fetcher->getUpdateChannel() == 'daily';
76 2
			if (!$isDailyChannel){
77 2
				$md5 = $this->fetcher->getMd5($feed);
78 2
			} else {
79
				// We can't check md5 so we don't trust the cache
80
				$this->fsHelper->removeIfExists($path);
81
			}
82 2
			if ($isDailyChannel || !$this->checkIntegrity($path, $md5)){
0 ignored issues
show
Bug introduced by
The variable $md5 does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
83 1
				$this->fetcher->getOwncloud($feed, $progressCallback);
84
			}
85
86 1
			if ($isDailyChannel || $this->checkIntegrity($path, $md5)){
87 1
				$response['success'] = true;
88 1
				$response['data']['path'] = $path;
89 1
			} else {
90
				$response['exception'] = new \Exception('Deleted ' . $feed->getDownloadedFileName() . ' due to wrong checksum');
91
			}
92 2
		} catch (\Exception $e) {
93 1
			if (isset($path)){
94 1
				$this->fsHelper->removeIfExists($path);
95 1
			}
96 1
			$response['exception'] = $e;
97
		}
98 2
		return $response;
99
	}
100
101
	/**
102
	 * Check if package is not corrupted on download
103
	 * @param string $path
104
	 * @param string $md5
105
	 * @return boolean
106
	 */
107 2
	protected function checkIntegrity($path, $md5){
108 2
			$fileExists = $this->fsHelper->fileExists($path);
109 2
			$checksumMatch = $md5 === $this->fsHelper->md5File($path);
110 2
			if ($fileExists && !$checksumMatch){
111 1
				$this->fsHelper->removeIfExists($path);
112 1
				$fileExists = false;
113 1
			}
114 2
			return $fileExists;
115
	}
116
117
	/**
118
	 * Get a Feed instance
119
	 * @param bool $useCache
120
	 * @return \Owncloud\Updater\Utils\Feed
121
	 */
122 2
	protected function getFeed($useCache = true){
123 2
		if ($useCache && !is_null($this->registry->get('feed'))){
124 2
			return $this->registry->get('feed');
125
		}
126
		return $this->fetcher->getFeed();
127
	}
128
129
	/**
130
	 * Init response array
131
	 * @return array
132
	 */
133 4
	protected function getDefaultResponse(){
134
		return [
135 4
			'success' => false,
136 4
			'exception' => '',
137 4
			'details' => '',
138 4
			'data' => []
139 4
		];
140
	}
141
}
142