Commit ebc5d852 authored by David Rothstein's avatar David Rothstein
Browse files

Issue #1003788 by stefan.r, Alan D., JimmyAx, Josh Waihi, john_brown, twistor,...

Issue #1003788 by stefan.r, Alan D., JimmyAx, Josh Waihi, john_brown, twistor, bellHead, bzrudi71, pwolanin, gaas, wiifm, robhardwick, gngn: PostgreSQL PDOException: Invalid text representation when attempting to load an entity with a string or non-scalar ID
parent edf23f20
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line

Drupal 7.37, xxxx-xx-xx (development version)
-----------------------
- Fixed PDO exceptions on PostgreSQL when accessing invalid entity URLs.
- Added a sites/all/libraries folder to the codebase, with instructions for
  using it.
- Added a description to the "Administer text formats and filters" permission
+18 −0
Original line number Diff line number Diff line
@@ -7137,6 +7137,23 @@ function _drupal_schema_initialize(&$schema, $module, $remove_descriptions = TRU
  }
}

/**
 * Retrieves the type for every field in a table schema.
 *
 * @param $table
 *   The name of the table from which to retrieve type information.
 *
 * @return
 *   An array of types, keyed by field name.
 */
function drupal_schema_field_types($table) {
  $table_schema = drupal_get_schema($table);
  foreach ($table_schema['fields'] as $field_name => $field_info) {
    $field_types[$field_name] = isset($field_info['type']) ? $field_info['type'] : NULL;
  }
  return $field_types;
}

/**
 * Retrieves a list of fields from a table schema.
 *
@@ -7761,6 +7778,7 @@ function entity_get_info($entity_type = NULL) {
        // Prepare entity schema fields SQL info for
        // DrupalEntityControllerInterface::buildQuery().
        if (isset($entity_info[$name]['base table'])) {
          $entity_info[$name]['base table field types'] = drupal_schema_field_types($entity_info[$name]['base table']);
          $entity_info[$name]['schema_fields_sql']['base table'] = drupal_schema_fields_sql($entity_info[$name]['base table']);
          if (isset($entity_info[$name]['revision table'])) {
            $entity_info[$name]['schema_fields_sql']['revision table'] = drupal_schema_fields_sql($entity_info[$name]['revision table']);
+34 −0
Original line number Diff line number Diff line
@@ -183,6 +183,11 @@ public function load($ids = array(), $conditions = array()) {
      }
    }

    // Ensure integer entity IDs are valid.
    if (!empty($ids)) {
      $this->cleanIds($ids);
    }

    // Load any remaining entities from the database. This is the case if $ids
    // is set to FALSE (so we load all entities), if there are any ids left to
    // load, if loading a revision, or if $conditions was passed without $ids.
@@ -223,6 +228,35 @@ public function load($ids = array(), $conditions = array()) {
    return $entities;
  }

  /**
   * Ensures integer entity IDs are valid.
   *
   * The identifier sanitization provided by this method has been introduced
   * as Drupal used to rely on the database to facilitate this, which worked
   * correctly with MySQL but led to errors with other DBMS such as PostgreSQL.
   *
   * @param array $ids
   *   The entity IDs to verify. Non-integer IDs are removed from this array if
   *   the entity type requires IDs to be integers.
   */
  protected function cleanIds(&$ids) {
    $entity_info = entity_get_info($this->entityType);
    if (isset($entity_info['base table field types'])) {
      $id_type = $entity_info['base table field types'][$this->idKey];
      if ($id_type == 'serial' || $id_type == 'int') {
        $ids = array_filter($ids, array($this, 'filterId'));
        $ids = array_map('intval', $ids);
      }
    }
  }

  /**
   * Callback for array_filter that removes non-integer IDs.
   */
  protected function filterId($id) {
    return is_numeric($id) && $id == (int) $id;
  }

  /**
   * Builds the query to load the entity.
   *
+5 −0
Original line number Diff line number Diff line
@@ -1068,6 +1068,11 @@ class PageNotFoundTestCase extends DrupalWebTestCase {
    );
    $node = $this->drupalCreateNode($edit);

    // As node IDs must be integers, make sure requests for non-integer IDs
    // return a page not found error.
    $this->drupalGet('node/invalid');
    $this->assertResponse(404);

    // Use a custom 404 page.
    $this->drupalPost('admin/config/system/site-information', array('site_404' => 'node/' . $node->nid), t('Save configuration'));