Repository: symfony/symfony
File: src/Symfony/Component/JsonStreamer/Write/PhpGenerator.php (PHP)

Code before:
    {
        if ('' === $this->yieldBuffer) {
            return '';
        }

        $yieldBuffer = $this->yieldBuffer;
        $this->yieldBuffer = '';

        return $this->yield('"'.$yieldBuffer.'"', $context);
    }

    private function generateCompositeNodeItemCondition(DataModelNodeInterface $node): string
    {
        $accessor = $node->getAccessor();
        $type = $node->getType();

        if ($type->isIdentifiedBy(TypeIdentifier::NULL, TypeIdentifier::NEVER, TypeIdentifier::VOID)) {
            return "null === $accessor";
        }

        if ($type->isIdentifiedBy(TypeIdentifier::TRUE)) {
            return "true === $accessor";
        }

        if ($type->isIdentifiedBy(TypeIdentifier::FALSE)) {
            return "false === $accessor";
        }

        if ($type->isIdentifiedBy(TypeIdentifier::MIXED)) {
            return 'true';
        }

        while ($type instanceof WrappingTypeInterface) {
            $type = $type->getWrappedType();
        }

        if ($type instanceof ObjectType) {
            return "$accessor instanceof \\".$type->getClassName();
        }

        if ($type instanceof BuiltinType) {
            return '\\is_'.$type->getTypeIdentifier()->value."($accessor)";
        }

        throw new LogicException(\sprintf('Unexpected "%s" type.', $type::class));
    }

    /**
     * @param array<string, mixed> $context
     */
    private function line(string $line, array $context): string

Review comment (security):
be careful. Using double quotes unlocks many escape sequences in PHP, and `yieldString` does not perform any escaping (except for `$` now) so it expects the caller to pass a string being the content of a string literal, instead of being the content of the string it wants to yield.
Are we sure that there is nothing impacted by that ? We might have injection of escape sequences rather than injection of interpolation.

Btw, `yieldString` might need to be renamed if it is not about yielding the given string (taking care internally of turning it into a PHP string literal with proper escaping) but about yielding some string literal instead (where the caller has to deal with escaping), in order to reduce the risk of confusion for future contributors

Code after:
            .$this->line("yield $value;", $context);
    }

    /**
     * @param array<string, mixed> $context
     */
    private function yieldInterpolatedString(string $string, array $context, bool $escapeDollar = true): string
    {
        $this->yieldBuffer .= addcslashes($string, "\\\"\n\r\t\v\e\f".($escapeDollar ? '$' : ''));

        return '';
    }

    /**
     * @param array<string, mixed> $context
     */
    private function flushYieldBuffer(array $context): string
    {
        if ('' === $this->yieldBuffer) {
            return '';
        }

        $yieldBuffer = $this->yieldBuffer;
        $this->yieldBuffer = '';

        return $this->yield('"'.$yieldBuffer.'"', $context);
    }

    private function generateCompositeNodeItemCondition(DataModelNodeInterface $node): string
    {
        $accessor = $node->getAccessor();
        $type = $node->getType();

        if ($type->isIdentifiedBy(TypeIdentifier::NULL, TypeIdentifier::NEVER, TypeIdentifier::VOID)) {
            return "null === $accessor";
        }

        if ($type->isIdentifiedBy(TypeIdentifier::TRUE)) {
            return "true === $accessor";
        }

        if ($type->isIdentifiedBy(TypeIdentifier::FALSE)) {
            return "false === $accessor";
        }

        if ($type->isIdentifiedBy(TypeIdentifier::MIXED)) {
            return 'true';
        }

        while ($type instanceof WrappingTypeInterface) {
            $type = $type->getWrappedType();