GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Issues (423)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

application/libraries/Migration.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 52 and the first side effect is on line 38.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
/**
3
 * CodeIgniter
4
 *
5
 * An open source application development framework for PHP
6
 *
7
 * This content is released under the MIT License (MIT)
8
 *
9
 * Copyright (c) 2014 - 2015, British Columbia Institute of Technology
10
 *
11
 * Permission is hereby granted, free of charge, to any person obtaining a copy
12
 * of this software and associated documentation files (the "Software"), to deal
13
 * in the Software without restriction, including without limitation the rights
14
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
 * copies of the Software, and to permit persons to whom the Software is
16
 * furnished to do so, subject to the following conditions:
17
 *
18
 * The above copyright notice and this permission notice shall be included in
19
 * all copies or substantial portions of the Software.
20
 *
21
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27
 * THE SOFTWARE.
28
 *
29
 * @package CodeIgniter
30
 * @author  EllisLab Dev Team
31
 * @copyright   Copyright (c) 2008 - 2014, EllisLab, Inc. (http://ellislab.com/)
32
 * @copyright   Copyright (c) 2014 - 2015, British Columbia Institute of Technology (http://bcit.ca/)
33
 * @license http://opensource.org/licenses/MIT  MIT License
34
 * @link    http://codeigniter.com
35
 * @since   Version 3.0.0
36
 * @filesource
37
 */
38
defined('BASEPATH') OR exit('No direct script access allowed');
39
40
/**
41
 * Migration Class
42
 *
43
 * All migrations should implement this, forces up() and down() and gives
44
 * access to the CI super-global.
45
 *
46
 * @package     CodeIgniter
47
 * @subpackage  Libraries
48
 * @category    Libraries
49
 * @author      Reactor Engineers
50
 * @link
51
 */
52
class CI_Migration {
53
54
    /**
55
     * Whether the library is enabled
56
     *
57
     * @var bool
58
     */
59
    protected $_migration_enabled = FALSE;
60
61
    /**
62
     * Migration numbering type
63
     *
64
     * @var	bool
65
     */
66
    protected $_migration_type = 'sequential';
67
68
    /**
69
     * Path to migration classes
70
     *
71
     * @var string
72
     */
73
    protected  $_migration_paths = NULL;
74
75
    /**
76
     * Current migration version
77
     *
78
     * @var mixed
79
     */
80
    protected $_migration_version = 0;
81
82
    /**
83
     * Database table with migration info
84
     *
85
     * @var string
86
     */
87
    protected $_migration_table = 'migrations';
88
89
    /**
90
     * Whether to automatically run migrations
91
     *
92
     * @var	bool
93
     */
94
    protected $_migration_auto_latest = FALSE;
95
96
    /**
97
     * Migration basename regex
98
     *
99
     * @var bool
100
     */
101
    protected $_migration_regex = NULL;
102
103
    /**
104
     * Error message
105
     *
106
     * @var string
107
     */
108
    protected $_error_string = '';
109
110
    /**
111
     * Initialize Migration Class
112
     *
113
     * @param	array	$config
114
     * @return	void
115
     */
116
    public function __construct($config = array())
117
    {
118
        // Only run this constructor on main library load
119 View Code Duplication
        if ( ! in_array(get_class($this), array('CI_Migration', config_item('subclass_prefix').'Migration'), TRUE))
120
        {
121
            return;
122
        }
123
124
        foreach ($config as $key => $val)
125
        {
126
            $this->{'_'.$key} = $val;
127
        }
128
129
        log_message('debug', 'Migrations class initialized');
130
131
        // Are they trying to use migrations while it is disabled?
132
        if ($this->_migration_enabled !== TRUE)
133
        {
134
            show_error('Migrations has been loaded but is disabled or set up incorrectly.');
135
        }
136
137
        // If not set, set it
138
        count($this->_migration_paths) OR $this->_migration_paths = array(APPPATH.'database/migrations/');
139
140
        // Add trailing slash if not set
141
        foreach ($this->_migration_paths as $alias => $path) {
142
            $this->_migration_paths[$alias] = rtrim($this->_migration_paths[$alias], '/') . '/';
143
        }
144
145
        // Load migration language
146
        $this->lang->load('migration');
147
148
        // They'll probably be using dbforge
149
        $this->load->dbforge();
150
151
        // Make sure the migration table name was set.
152
        if (empty($this->_migration_table))
153
        {
154
            show_error('Migrations configuration file (migration.php) must have "migration_table" set.');
155
        }
156
157
        // Migration basename regex
158
        $this->_migration_regex = ($this->_migration_type === 'timestamp')
159
            ? '/^\d{14}_(\w+)$/'
160
            : '/^\d{3}_(\w+)$/';
161
162
        // Make sure a valid migration numbering type was set.
163 View Code Duplication
        if ( ! in_array($this->_migration_type, array('sequential', 'timestamp')))
164
        {
165
            show_error('An invalid migration numbering type was specified: '.$this->_migration_type);
166
        }
167
168
        // If the migrations table is missing, make it
169
        if ( ! $this->db->table_exists($this->_migration_table))
170
        {
171
            $this->dbforge->add_field(array(
172
                'version' => array('type' => 'BIGINT', 'constraint' => 20),
173
                'alias' => array('type' => 'VARCHAR', 'constraint' => 255),
174
                'ondate'  => array('type' => 'DATETIME')
175
            ));
176
177
            $this->dbforge->add_key('alias');
178
179
            $this->dbforge->create_table($this->_migration_table, TRUE);
180
        }
181
182
        // Do we auto migrate to the latest migration?
183
        if ($this->_migration_auto_latest === TRUE && ! $this->latest())
184
        {
185
            show_error($this->error_string());
186
        }
187
188
    }
189
190
    // --------------------------------------------------------------------
191
192
    /**
193
     * Migrate to a schema version
194
     *
195
     * Calls each migration step required to get to the schema version of
196
     * choice
197
     *
198
     * @param string $type  Any key from _migration_paths, or {module_name}
199
     * @param	string	$target_version	Target schema version
200
     *
201
     * @return	mixed	TRUE if already latest, FALSE if failed, string if upgraded
202
     */
203
    public function version($type='all', $target_version)
204
    {
205
        // Note: We use strings, so that timestamp versions work on 32-bit systems
206
        $current_version = $this->get_version($type);
207
208 View Code Duplication
        if ($this->_migration_type === 'sequential')
209
        {
210
            $target_version = sprintf('%03d', $target_version);
211
        }
212
        else
213
        {
214
            $target_version = (string) $target_version;
215
        }
216
217
        $migrations = $this->find_migrations($type);
218
219 View Code Duplication
        if ($target_version > 0 && ! isset($migrations[$target_version]))
220
        {
221
            $this->_error_string = sprintf($this->lang->line('migration_not_found'), $target_version);
222
            return FALSE;
223
        }
224
225
        if ($target_version > $current_version)
226
        {
227
            // Moving Up
228
            $method = 'up';
229
        }
230
        else
231
        {
232
            // Moving Down, apply in reverse order
233
            $method = 'down';
234
            krsort($migrations);
235
        }
236
237
        if (empty($migrations))
238
        {
239
            return TRUE;
240
        }
241
242
        $previous = FALSE;
243
244
        // Validate all available migrations, and run the ones within our target range
245 View Code Duplication
        foreach ($migrations as $number => $file)
246
        {
247
            // Check for sequence gaps
248
            if ($this->_migration_type === 'sequential' && $previous !== FALSE && abs($number - $previous) > 1)
249
            {
250
                $this->_error_string = sprintf($this->lang->line('migration_sequence_gap'), $number);
251
                return FALSE;
252
            }
253
254
            include_once($file);
255
            $class = 'Migration_'.ucfirst(strtolower($this->_get_migration_name(basename($file, '.php'))));
256
257
            // Validate the migration file structure
258
            if ( ! class_exists($class, FALSE))
259
            {
260
                $this->_error_string = sprintf($this->lang->line('migration_class_doesnt_exist'), $class);
261
                return FALSE;
262
            }
263
264
            $previous = $number;
265
266
            // Run migrations that are inside the target range
267
            if (
268
                ($method === 'up'   && $number > $current_version && $number <= $target_version) OR
269
                ($method === 'down' && $number <= $current_version && $number > $target_version)
270
            )
271
            {
272
                $instance = new $class();
273
                if ( ! is_callable(array($instance, $method)))
274
                {
275
                    $this->_error_string = sprintf($this->lang->line('migration_missing_'.$method.'_method'), $class);
276
                    return FALSE;
277
                }
278
279
                log_message('debug', 'Migrating '.$method.' from version '.$current_version.' to version '.$number);
280
                call_user_func(array($instance, $method));
281
                $current_version = $number;
282
                $this->_update_version($type, $current_version);
283
            }
284
        }
285
286
        // This is necessary when moving down, since the the last migration applied
287
        // will be the down() method for the next migration up from the target
288
        if ($current_version <> $target_version)
289
        {
290
            $current_version = $target_version;
291
            $this->_update_version($type, $current_version);
292
        }
293
294
        log_message('debug', 'Finished migrating to '.$current_version);
295
296
        return $current_version;
297
    }
298
299
    // --------------------------------------------------------------------
300
301
    /**
302
     * Sets the schema to the latest migration
303
     *
304
     * @param string $type  Any key from _migration_paths, or {module_name}
305
     *
306
     * @return	mixed	TRUE if already latest, FALSE if failed, string if upgraded
307
     */
308
    public function latest($type='app')
309
    {
310
        $last_migration = $this->get_latest($type);
311
312
        // Calculate the last migration step from existing migration
313
        // filenames and proceed to the standard version migration
314
        return $this->version($type, $this->_get_migration_number($last_migration));
0 ignored issues
show
It seems like $last_migration defined by $this->get_latest($type) on line 310 can also be of type false; however, CI_Migration::_get_migration_number() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
315
    }
316
317
    // --------------------------------------------------------------------
318
319
    /**
320
     * Retrieves the latest migration version available.
321
     *
322
     * @param string $type  Any key from _migration_paths, or {module_name}
323
     *
324
     * @return bool|string
325
     */
326
    public function get_latest($type='app')
327
    {
328
        $migrations = $this->find_migrations($type);
329
330
        if (empty($migrations))
331
        {
332
            $this->_error_string = $this->lang->line('migration_none_found');
333
            return FALSE;
334
        }
335
336
        return basename(end($migrations));
337
    }
338
339
    //--------------------------------------------------------------------
340
341
342
343
    /**
344
     * Sets the schema to the migration version set in config
345
     *
346
     * @return	mixed	TRUE if already current, FALSE if failed, string if upgraded
347
     */
348
    public function current()
349
    {
350
        return $this->version($this->_migration_version);
351
    }
352
353
    // --------------------------------------------------------------------
354
355
    /**
356
     * Error string
357
     *
358
     * @return	string	Error message returned as a string
359
     */
360
    public function error_string()
361
    {
362
        return $this->_error_string;
363
    }
364
365
    // --------------------------------------------------------------------
366
367
    /**
368
     * Retrieves list of available migration scripts
369
     *
370
     * @return	array	list of migration file paths sorted by version
371
     */
372
    public function find_migrations($type='app')
373
    {
374
        $migrations = array();
375
376
        $path = $this->determine_migration_path($type);
377
378
        // Load all *_*.php files in the migrations path
379 View Code Duplication
        foreach (glob($path.'*_*.php') as $file)
380
        {
381
            $name = basename($file, '.php');
382
383
            // Filter out non-migration files
384
            if (preg_match($this->_migration_regex, $name))
385
            {
386
                $number = $this->_get_migration_number($name);
387
388
                // There cannot be duplicate migration numbers
389
                if (isset($migrations[$number]))
390
                {
391
                    $this->_error_string = sprintf($this->lang->line('migration_multiple_version'), $number);
392
                    show_error($this->_error_string);
393
                }
394
395
                $migrations[$number] = $file;
396
            }
397
        }
398
399
        ksort($migrations);
400
        return $migrations;
401
    }
402
403
    // --------------------------------------------------------------------
404
405
    /**
406
     * Retrieves current schema version
407
     *
408
     * @return	string	Current migration version
409
     */
410
    public function get_version($type='app')
411
    {
412
        $row = $this->db->select('version')
413
                        ->where('alias', $type)
414
                        ->get($this->_migration_table)
415
                        ->row();
416
417
        return $row ? $row->version : '0';
418
    }
419
420
    // --------------------------------------------------------------------
421
422
    /**
423
     * Given the string for the name of the file, will
424
     * generate the rest of the filename based on the current
425
     * $config['migration_type'] setting.
426
     *
427
     * @param $name
428
     * @return string The final name (with extension)
429
     */
430
    public function make_name($name)
431
    {
432
        if (empty($name))
433
        {
434
            return null;
435
        }
436
437
        if ($this->_migration_type == 'timestamp')
438
        {
439
            $prefix = date('YmdHis');
440
        }
441
        else
442
        {
443
            $prefix = str_pad($this->get_version() + 1, 3, '0', STR_PAD_LEFT);
444
        }
445
446
        return $prefix .'_'. ucfirst(strtolower($name)) .'.php';
447
    }
448
449
    //--------------------------------------------------------------------
450
451
    /**
452
     * Enable the use of CI super-global
453
     *
454
     * @param	string	$var
455
     * @return	mixed
456
     */
457
    public function __get($var)
458
    {
459
        return get_instance()->$var;
460
    }
461
462
    //--------------------------------------------------------------------
463
464
465
	/**
466
	 * Based on the 'type', determines the correct migration path.
467
	 *
468
	 * @param $type
469
	 * @param bool $create
470
	 *
471
	 * @return null|string
472
	 */
473
    public function determine_migration_path($type, $create=false)
474
    {
475
        $type = strtolower($type);
476
477
        // Is it a module?
478
        if (strpos($type, 'mod:') === 0)
479
        {
480
            $module = str_replace('mod:', '', $type);
481
482
            $path = \Myth\Modules::path($module, 'migrations');
483
484
	        // Should we return a 'created' module?
485
	        // Use the first module path.
486
	        if (empty($path) && $create === true)
487
	        {
488
				$folders = config_item('modules_locations');
489
490
		        if (is_array($folders) && count($folders))
491
		        {
492
			        $path = $folders[0] . $module .'/migrations';
493
		        }
494
	        }
495
496
            return rtrim($path, '/') .'/';
497
        }
498
499
        // Look in our predefined groups.
500
        if (! empty($this->_migration_paths[$type]))
501
        {
502
            return rtrim($this->_migration_paths[$type], '/') .'/';
503
        }
504
505
        return null;
506
    }
507
508
    //--------------------------------------------------------------------
509
510
    /**
511
     * Returns the default migration path. This is basically the first
512
     * path in the migration_paths array.
513
     *
514
     * @return string
515
     */
516
    public function default_migration_path()
517
    {
518
        return key($this->_migration_paths);
519
    }
520
521
    //--------------------------------------------------------------------
522
523
524
    //--------------------------------------------------------------------
525
    // Protected Methods
526
    //--------------------------------------------------------------------
527
528
    /**
529
     * Extracts the migration number from a filename
530
     *
531
     * @param	string	$migration
532
     * @return	string	Numeric portion of a migration filename
533
     */
534
    protected function _get_migration_number($migration)
535
    {
536
        return sscanf($migration, '%[0-9]+', $number)
537
            ? $number : '0';
538
    }
539
540
    // --------------------------------------------------------------------
541
542
    /**
543
     * Extracts the migration class name from a filename
544
     *
545
     * @param	string	$migration
546
     * @return	string	text portion of a migration filename
547
     */
548
    protected function _get_migration_name($migration)
549
    {
550
        $parts = explode('_', $migration);
551
        array_shift($parts);
552
        return implode('_', $parts);
553
    }
554
555
    // --------------------------------------------------------------------
556
557
    /**
558
     * Stores the current schema version
559
     *
560
     * @param   string  $type  Any key from _migration_paths, or {module_name}
561
     * @param	string	$migration	Migration reached
562
     * @return	mixed	Outputs a report of the migration
563
     */
564
    protected function _update_version($type='all', $migration)
565
    {
566
        $this->db->where('alias', $type)
567
                 ->delete($this->_migration_table);
568
569
        return $this->db->insert($this->_migration_table, array(
570
            'version'   => $migration,
571
            'alias'     => $type,
572
            'ondate'    => date('Y-m-d H:i:s')
573
        ));
574
    }
575
576
    // --------------------------------------------------------------------
577
578
}
579