Browse files

Throw exceptions when non Datasource classes are used as Datasources.

Using models as datasources can cause segmentation faults. Guard against
that by checking types and raising exceptions early.

Fixes #3694
  • Loading branch information...
1 parent 73310f9 commit 3d4ebc038cc3336a11a263eca5f465b05cfce896 @markstory markstory committed Mar 13, 2013
2 lib/Cake/Error/exceptions.php
@@ -441,7 +441,7 @@ class MissingDatasourceConfigException extends CakeException {
class MissingDatasourceException extends CakeException {
- protected $_messageTemplate = 'Datasource class %s could not be found.';
+ protected $_messageTemplate = 'Datasource class %s could not be found. %s';
12 lib/Cake/Model/ConnectionManager.php
@@ -99,9 +99,17 @@ public static function getDataSource($name) {
$conn = self::$_connectionsEnum[$name];
$class = $conn['classname'];
- self::$_dataSources[$name] = new $class(self::$config->{$name});
- self::$_dataSources[$name]->configKeyName = $name;
+ $instance = new $class(self::$config->{$name});
+ $instance->configKeyName = $name;
+ if (!$instance instanceof Datasource) {
+ throw new MissingDatasourceException(array(
+ 'class' => $class,
+ 'plugin' => null,
+ 'message' => 'Only classes extending Datasource can be used as datasources.'
+ ));
+ }
+ self::$_dataSources[$name] = $instance;
return self::$_dataSources[$name];
3 lib/Cake/View/Errors/missing_datasource.ctp
@@ -22,6 +22,9 @@ $pluginDot = empty($plugin) ? null : $plugin . '.';
<p class="error">
<strong><?php echo __d('cake_dev', 'Error'); ?>: </strong>
<?php echo __d('cake_dev', 'Datasource class %s could not be found.', '<em>' . $pluginDot . $class . '</em>'); ?>
+ <?php if (isset($message)): ?>
+ <?php echo h($message); ?>
+ <?php endif; ?>
<p class="notice">
<strong><?php echo __d('cake_dev', 'Notice'); ?>: </strong>

10 comments on commit 3d4ebc0

CakePHP member

Ouch, that is not a very happy thing for me. I use tons of datasources that do not extend the base class :(

CakePHP member

If I understand the related ticket correctly, he provided incorrect value for datasource key in config and coincidentally there was a model class loaded of the same name which got used as datasource instance. Is that right? This sounds like a pretty rare edge case.

Given the fact that web services can be pretty varied in nature I am sure there must be others like @lorenzo who have made datasource class which don't extend the base class.

CakePHP member

👍 for undoing this

CakePHP member

I didn't want to try and check for things like using a model/controller/helper/component/behavior. Right now the failure case is a segmentation fault. I'm open for other ways of fixing this though. Perhaps we can sniff a method?

CakePHP member
CakePHP member

I don't think that would solve the issue of doing:

public $someConfg = array(
   'datasource' => 'Post'

And the app having a Model class, that may already be loaded.

CakePHP member

How about checking that if datasource's value doesn't contain a / it should end in source ?

CakePHP member

i meant sth like:

    if (strpos(App::location($className), 'Datasource') === false) {
        throw new Exception();
CakePHP member

@ceeram That sounds promising.

CakePHP member

Made a pull request: #1176

Please sign in to comment.