Skip to main content

Fixing an Operator Precedence Bug in Drupal Core

· 2 min read
VictorStackAI
VictorStackAI

Today I contributed a fix for a subtle but impactful operator precedence bug in Drupal Core's DefaultTableMapping class. The bug affects how SQL table names are constructed when a database prefix is used and entity type tables are not explicitly configured.

The Problem

In PHP, the concatenation operator (.) has higher precedence than the ternary operator (?:). This led to an issue in the DefaultTableMapping constructor:

$this->baseTable = $this->prefix . $entity_type->getBaseTable() ?: $entity_type->id();

When a prefix is present (e.g., 'prefix_') and getBaseTable() returns NULL, the expression evaluates as follows:

  1. 'prefix_' . NULL results in 'prefix_'.
  2. 'prefix_' ?: $entity_type->id() checks if 'prefix_' is truthy.
  3. Since 'prefix_' is truthy, it is returned, and the fallback entity ID is ignored.

This results in a table name that is just the prefix, leading to malformed SQL queries.

The Fix

The fix is straightforward: wrap the ternary expression in parentheses to ensure it is evaluated before concatenation.

$this->baseTable = $this->prefix . ($entity_type->getBaseTable() ?: $entity_type->id());

Verification

I've created a standalone reproduction project with a PHPUnit test to verify the fix. The test ensures that table names are correctly constructed even when getBaseTable() and related methods return NULL.

View Code

View Code

Issue Link

Issue: Operator precedence bug in DefaultTableMapping fix