In PuSHSubscriber::subscribe(), a curl request is sent to retrieve an Atom string. That Atom string is then parsed with SimpleXml for processing, and if there is a failure an exception is caught. Or, that's what's supposed to happen.
public function subscribe($url, $callback_url, $hub = '') {
// Fetch document, find rel=hub and rel=self.
// If present, issue subscription request.
$request = curl_init($url);
curl_setopt($request, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($request, CURLOPT_RETURNTRANSFER, TRUE);
$data = curl_exec($request);
if (curl_getinfo($request, CURLINFO_HTTP_CODE) == 200) {
try {
$xml = @ new SimpleXMLElement($data);
$xml->registerXPathNamespace('atom', 'http://www.w3.org/2005/Atom');
if (empty($hub) && $hub = @current($xml->xpath("//atom:link[attribute::rel='hub']"))) {
$hub = (string) $hub->attributes()->href;
}
if ($self = @current($xml->xpath("//atom:link[attribute::rel='self']"))) {
$self = (string) $self->attributes()->href;
}
}
catch (Exception $e) {
// Do nothing.
}
}
curl_close($request);
// Fall back to $url if $self is not given.
if (!$self) {
$self = $url;
}
if (!empty($hub) && !empty($self)) {
$this->request($hub, $self, 'subscribe', $callback_url);
}
}
Instead, the SimpleXml parsing is hidden with an @, and the exception that gets emitted is caught and simply discarded. There is even a comment that says "do nothing". The only error that anyone sees if something goes wrong with the Feed is a notice that $self is not defined... which besides being useless is a separate error as well since the code that requires $self shouldn't be running anyway. That is, the code actively prevents you from being able to debug an invalid feed.
While it's understandable to not want to display random SimpleXml errors to the user, it is not acceptable to silently swallow an exception without documentation as to why it's a good idea. In this case, it is not a good idea. Rather:
1) The @ sign should be removed. (I can see the argument not to, so maybe not, but still, @ is always a code smell.)
2) The exception should be caught and handled properly. At bare minimum, $e->getMessage() should be logged.
3) If an exception is thrown, then the entire rest of the method should probably be skipped. Or if not, it should be corrected for the notice (because that is an error in its own right) and the code documented to explain why to run the rest of it.
Comments
Comment #1
megachrizClosed #3006899: error: Undefined variable: self as a duplicate.
The try-catch was added in #724184: Uncaught exception on new SimpleXMLElement with non-(valid)XML and the reason was probably that it broke the import process. It would have been better I think if the calling code would catch the exception.
Anyways,
if (!$self) {should probably becomeif (empty($self)) {.In commit de814baf the
@was added with the commit message "Suppress namespace warnings when parsing feeds for subscription in PuSHSubscriber.inc."Comment #2
bluegeek9 commentedDrupal 7 reached end of life and the D7 version of Feeds is no longer being developed. To keep the issue queue focused on supported versions, we’re closing older D7 issues.
If you still have questions about using Feeds on Drupal 7, feel free to ask. While we won’t fix D7 bugs anymore, we’re happy to offer guidance to help you move forward. You can do so by opening (or reopening) a D7 issue, or by reaching out in the #feeds channel on Drupal Slack.
If this issue is still relevant for Drupal 10+, please open a follow-up issue or merge request with proposed changes. Contributions are always welcome!