1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-25 16:22:43 +01:00

Fix important regression in search engine

Summary:
Interestingly Phorge allows to paste a Phorge URL in the search bar to be redirected there...

Now this interesting feature was crashing the whole search engine for simple queries like "asdasd"
with the following exception message:

    Refusing to redirect to local resource "asdasd". This URI is not formatted in a recognizable way.

You are affected by this crash after this commit:

328aee033f

This specific commit is probably legitimate since "#asdasd" and "/asdasd" are indeed internal URIs,
plus, yes, there are some undocumented and untested cases like "asdasd" that may be considered
internal URIs as well. Or not. But this is just an undocumented corner-case.

In short:

PhabricatorDatasourceURIEngineExtension should not be built over undocumented corner-cases and
should require an absolute URI, with at least a domain.

Note that PhutilURI#getDomain() is always a string and never null, so we can do a strict check.

This fix also involves a micro-optimization to avoid duplicate URI parsing. Since the method was calling
the constructor PhutilURI(string) twice (line 13, line 24). Now just once.

Closes T15763

Test Plan:
Search "lol", no crash anymore.

Copy a random Phorge URL and paste that in your search bar. It still redirects there.

Reviewers: zhe, avivey, O1 Blessed Committers, speck

Reviewed By: O1 Blessed Committers, speck

Subscribers: speck, tobiaswiese, Matthew, Cigaryno

Maniphest Tasks: T15763

Differential Revision: https://we.phorge.it/D25561
This commit is contained in:
Valerio Bozzolan 2024-03-26 07:29:53 +01:00
parent 9ebe856219
commit 27f4b8321a

View file

@ -10,35 +10,37 @@ final class PhabricatorDatasourceURIEngineExtension
public function newJumpURI($query) { public function newJumpURI($query) {
// If you search for a URI on the local install, just redirect to that // If you search for a URI on the local install, just redirect to that
// URI as though you had pasted it into the URI bar. // URI as though you had pasted it into the URI bar.
if (PhabricatorEnv::isSelfURI($query)) { // Skip things that are really not full URLs, like "asdasd".
// Strip off the absolute part of the URI. If we don't, the URI redirect // Note that the backend of "isSelfURI" is faster with a PhutilURI.
// validator will get upset that we're performing an unmarked external $uri = new PhutilURI($query);
// redirect. if ($uri->getDomain() === '' || !PhabricatorEnv::isSelfURI($uri)) {
return null;
// The correct host and protocol may also differ from the host and
// protocol used in the search: for example, if you search for "http://"
// we want to redirect to "https://" if an install is HTTPS, and
// the "isSelfURI()" check includes alternate domains in addition to the
// canonical domain.
$uri = id(new PhutilURI($query))
->setDomain(null)
->setProtocol(null)
->setPort(null);
$uri = phutil_string_cast($uri);
// See T13412. If the URI was in the form "http://dev.example.com" with
// no trailing slash, there may be no path. Redirecting to the empty
// string is considered an error by safety checks during redirection,
// so treat this like the user entered the URI with a trailing slash.
if (!strlen($uri)) {
$uri = '/';
}
return $uri;
} }
return null; // Strip off the absolute part of the URI. If we don't, the URI redirect
// validator will get upset that we're performing an unmarked external
// redirect.
// The correct host and protocol may also differ from the host and
// protocol used in the search: for example, if you search for "http://"
// we want to redirect to "https://" if an install is HTTPS, and
// the "isSelfURI()" check includes alternate domains in addition to the
// canonical domain.
$uri = $uri
->setDomain(null)
->setProtocol(null)
->setPort(null);
$uri = phutil_string_cast($uri);
// See T13412. If the URI was in the form "http://dev.example.com" with
// no trailing slash, there may be no path. Redirecting to the empty
// string is considered an error by safety checks during redirection,
// so treat this like the user entered the URI with a trailing slash.
if (!strlen($uri)) {
$uri = '/';
}
return $uri;
} }
} }