Page MenuHomePhabricator

D9444.id22545.diff
No OneTemporary

D9444.id22545.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -160,6 +160,7 @@
'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php',
'ArcanistSubversionHookAPI' => 'repository/hookapi/ArcanistSubversionHookAPI.php',
'ArcanistSvnHookPreCommitWorkflow' => 'workflow/ArcanistSvnHookPreCommitWorkflow.php',
+ 'ArcanistSymlinkLinter' => 'lint/linter/ArcanistSymlinkLinter.php',
'ArcanistTasksWorkflow' => 'workflow/ArcanistTasksWorkflow.php',
'ArcanistTestCase' => 'infrastructure/testing/ArcanistTestCase.php',
'ArcanistTextLinter' => 'lint/linter/ArcanistTextLinter.php',
@@ -326,6 +327,7 @@
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
'ArcanistSubversionHookAPI' => 'ArcanistHookAPI',
'ArcanistSvnHookPreCommitWorkflow' => 'ArcanistBaseWorkflow',
+ 'ArcanistSymlinkLinter' => 'ArcanistLinter',
'ArcanistTasksWorkflow' => 'ArcanistBaseWorkflow',
'ArcanistTestCase' => 'ArcanistPhutilTestCase',
'ArcanistTextLinter' => 'ArcanistLinter',
diff --git a/src/lint/linter/ArcanistSymlinkLinter.php b/src/lint/linter/ArcanistSymlinkLinter.php
new file mode 100644
--- /dev/null
+++ b/src/lint/linter/ArcanistSymlinkLinter.php
@@ -0,0 +1,80 @@
+<?php
+
+/**
+ * A linter which checks symbolic links.
+ */
+final class ArcanistSymlinkLinter extends ArcanistLinter {
+
+ const LINT_BROKEN_SYMLINK = 1;
+ const LINT_EXTERNAL_SYMLINK = 2;
+
+ public function getInfoName() {
+ return 'Symbolic Link';
+ }
+
+ public function getInfoDescription() {
+ return pht('Checks symbolic links.');
+ }
+
+ public function getLinterName() {
+ return 'SYMLINK';
+ }
+
+ public function getLinterConfigurationName() {
+ return 'symlink';
+ }
+
+ public function getLinterPriority() {
+ return 0.125;
+ }
+
+ protected function shouldLintBinaryFiles() {
+ return true;
+ }
+
+ protected function shouldLintDirectories() {
+ return true;
+ }
+
+ public function getLintNameMap() {
+ return array(
+ self::LINT_BROKEN_SYMLINK => pht('Broken Symlink'),
+ self::LINT_EXTERNAL_SYMLINK => pht('External Symlink'),
+ );
+ }
+
+ public function getLintSeverityMap() {
+ return array(
+ self::LINT_BROKEN_SYMLINK => ArcanistLintSeverity::SEVERITY_ERROR,
+ self::LINT_EXTERNAL_SYMLINK => ArcanistLintSeverity::SEVERITY_ADVICE,
+ );
+ }
+
+ public function lintPath($path) {
+ if (!is_link($path)) {
+ // If the file is not a symlink, don't bother.
+ return;
+ }
+
+ if (realpath($path) === false) {
+ $this->raiseLintAtPath(
+ self::LINT_BROKEN_SYMLINK,
+ pht('Broken symlinks should not exist.'));
+ $this->stopAllLinters();
+ }
+
+ if ($this->didStopAllLinters()) {
+ return;
+ }
+
+ $root = $this->getEngine()->getWorkingCopy()->getProjectRoot();
+ if (!Filesystem::isDescendant(realpath($path), $root)) {
+ $this->raiseLintAtPath(
+ self::LINT_EXTERNAL_SYMLINK,
+ pht(
+ 'Symlinks generally should not point outside of the working copy, '.
+ 'for portability reasons.'));
+ }
+ }
+
+}

File Metadata

Mime Type
text/plain
Expires
Mar 9 2025, 7:37 AM (5 w, 5 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7387420
Default Alt Text
D9444.id22545.diff (3 KB)

Event Timeline