Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check DefaultProcessor::handleMissingFields() for infinite loops #45

Open
mabar opened this issue Dec 5, 2022 · 1 comment
Open

Check DefaultProcessor::handleMissingFields() for infinite loops #45

mabar opened this issue Dec 5, 2022 · 1 comment

Comments

@mabar
Copy link
Member

mabar commented Dec 5, 2022

Auto-initialization of objects may lead to infinite loops in case of self-references. Needs test for verification.

Metadata-based detection is not possible - even object with all properties required may be still initializable due to before class callback. If no solution is found, feature may be just removed.

Solving it in runtime may not be viable - creating first object in structure and omiting same one deeper in structure is not deterministic behavior.

// Try to initialize object from empty array when no data given
// Mapped object in compound type is not supported (allOf, anyOf)
// Used only in default mode - if all or none values are required then we need differentiate whether user sent value or not
$mappedObjectArgs = $propertyMeta->getRule()->getArgs();
assert($mappedObjectArgs instanceof MappedObjectArgs);
try {
$data[$missingField] = $initializeObjects
? $this->process([], $mappedObjectArgs->type, $options)
: $this->processWithoutMapping([], $mappedObjectArgs->type, $options);
} catch (InvalidData $exception) {
$type->overwriteInvalidField(
$missingField,
InvalidData::create($exception->getType(), Value::none()),
);
}

@mabar
Copy link
Member Author

mabar commented Jan 16, 2023

It causes infinite loops. And fork before class callbacks. Unconditional self reference is simply wrong design.

Unconditional self reference should be forbidden during metadata validation.

Both direct and non-direct (A -> B -> C -> A) self references should be validated. But only MappedObjectRule must be inspected, it is the only case where auto-initialization is used.

use Orisai\ObjectMapper\Attributes\Expect\MappedObjectValue;
use Orisai\ObjectMapper\MappedObject;

final class UnconditionalSelfReferenceVO implements MappedObject
{

	/**
	 * @MappedObjectValue(UnconditionalSelfReferenceVO::class)
	 */
	public UnconditionalSelfReferenceVO $self;

}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

1 participant