Repository navigation
bugfix issue 1811 checkForBTSConnection security note
Issue #1811 — checkForBTSConnection() was dead code: the legacy "Bug Tracking System has failed" security note could never fire
| Issue | #1811 |
| Type | bug (legacy config check) |
| Fix commit |
c5206fd1e — lib/functions/configCheck.php (1 call site) |
| Severity | minor — a security note that silently never fired; no data loss, no crash |
| Status | FIXED, verified error-free |
checkForBTSConnection() is the legacy helper behind the
$TLS_bts_connection_problems note ("Connection to your Bug Tracking System has
failed: … Be careful this problem will degrade TestLink performance.",
locale/en_US/strings.txt:2582). It could never return false, so the note was
never added to the security notes on any legacy page, and — with the shipped
default config_check_warning_mode = 'FILE' (config.inc.php:361) — never
reached logs/config_check.txt either. A user whose Bug Tracking System was
down was given no warning at all.
While writing the reproduction for #1811 the reported root cause turned out to be
incomplete: the $g_bugInterface global really is gone from the tree, but a
DB-driven fallback had already been added to the function by commit
c21cbedd9 ("leftover changes from bug-fix run") and had landed on the default
branch without documentation and without closing the issue. The dead code had
simply moved one level up — the fallback works, but no caller ever passes a DB
handle, so it is unreachable.
Measured on 96bfc55c4 (pre-fix), with a tracker linked to a test project whose
uribase points at a closed local port (http://127.0.0.1:1, so connect()
fails in ~2 ms with ECONNREFUSED):
checkForBTSConnection($db) = false (2 ms) <- DB fallback works
checkForBTSConnection() = true (0 ms) <- this is what getSecurityNotes() passed
getSecurityNotes($db) = array (6 notes, none of them the BTS one)
grep -ci "Bug Tracking System has failed" logs/config_check.txt -> 0
| # | hop | location |
|---|---|---|
| 1 |
getSecurityNotes(&$db) decides whether the note belongs in the list |
lib/functions/configCheck.php:251 |
| 2 | it calls the checker with no argument |
lib/functions/configCheck.php:273 (pre-fix) |
| 3 | the checker needs a DB handle for its fallback and returns early without one | lib/functions/configCheck.php:340,351-353 |
| 4 | so $status_ok can never become false and $securityNotes[] = lang_get("bts_connection_problems") never runs |
lib/functions/configCheck.php:274 |
| 5 | both consumers therefore never receive the note |
login.php:230, lib/functions/common.php:1858 (initUserEnv()) |
Blast radius: checkForBTSConnection() has exactly one call site
(configCheck.php:273) and its output feeds initUserEnv(), which is used by
lib/execute/execDashboard.php, lib/results/*, lib/plan/planEdit.php,
lib/usermanagement/userInfo.php, lib/testcases/tcImport.php, … — and, in the
default FILE mode, logs/config_check.txt.
--- a/lib/functions/configCheck.php
+++ b/lib/functions/configCheck.php
@@ getSecurityNotes(&$db)
- if (!checkForBTSConnection()) {
+ if (!checkForBTSConnection($db) {
$securityNotes[] = lang_get("bts_connection_problems");
}Why this method and not the alternatives
-
Re-introduce
$g_bugInterface— rejected: no caller has the project-scoped context (login.phphas no project at all), and that is exactly the deletion that created the bug. - Delete the fallback and the note — rejected: it would silently drop a check 1.9.20 performed, with its strings still shipped in every locale bundle.
-
Reuse
install_check_bts_connection()(api/install/index.php:191-257, issue #1282) — rejected: that is a request script that emits JSON and callstLog(); the legacy include chain must not depend on it. The two checks run in different contexts (the installer has no project session), so they stay separate.
getSecurityNotes(&$db) already holds the handle (by reference) and the checker
takes it by value, so no call-site semantics change.
tmp/fixtures_1811.php (fixture: project + test plan + type-15 tracker on a closed
port, linked) and tmp/verify_1811.php (8-case matrix; any E_WARNING /
E_NOTICE / E_USER_* inside the check fails the run).
| case | expected | observed | verdict |
|---|---|---|---|
| A — no tracker linked |
true, no note |
true, no note |
PASS |
B — linked tracker, connect() fails |
false, note present, fast, no new events row |
false, note present, 3 ms, 0 new rows |
PASS |
C — linked tracker, unknown type
|
degrades to "failed", no diagnostic |
false, 0 new rows |
PASS |
D — shipped FILE mode |
note in logs/config_check.txt
|
written, grep -c → 1 |
PASS |
E — GET /login.php anonymous |
200, no Error/Warning |
200 in 0.073 s, only INFO audit row |
PASS |
F — legacy controller as admin
|
200, note in config_check.txt, no new events |
200 / 3 981 bytes, note present, 0 events matching %configCheck%/%bts%
|
PASS |
G — default ONCE_FOR_SESSION
|
computed once per session | not recomputed on the 2nd request, as in 1.9.20 | PASS |
| H — Event Viewer after the run | nothing new from this change | only pre-existing execDashboard.php:205-206 warnings → #1813
|
PASS |
Post-fix logs/config_check.txt (shipped FILE mode, produced by a real HTTP
request to lib/execute/execDashboard.php):
Install directory should be removed!
You should change the default password for the 'admin' account!
Connection to your Bug Tracking System has failed:<br />
Please check your configuration.<br />
Be careful this problem will degrade TestLink performance.
Check following parameters of email feature:
...
Cost: the check runs at most once per session
(config_check_warning_frequence = 'ONCE_FOR_SESSION', config.inc.php:367) and
only over trackers linked to a project — the same objects
tlIssueTracker::getInterfaceObject() already connects on every BTS-enabled
screen. With no BTS configured it is not executed at all (case A).
The notes are computed again but no screen in 2.0.1 renders them:
gui/templates/tl-classic/mainPage.tpl:83 is the only legacy renderer and
mainPage.php was replaced by gui/templates/mainpage/mainPage.html
(lib/general/mainPage.php:16, index.php:88-94); the modern Home screen has no
config-check banner; only the Install screen has its own implementation
(api/install/index.php). That display gap is filed as #1814 (enhancement) —
deliberately not smuggled into a one-line bug fix.
-
#1813 (bug) —
lib/execute/execDashboard.php:205-206raises 2 ×E_WARNING "Trying to access array offset on false"per load when the plan has no builds ($buildMgr->get_by_id()returnsfalse; the guard used 3 lines below at:209is missing on the two reads above it). -
#1815 (bug) — PHP 8.2
E_DEPRECATED: Creation of dynamic property …forredminerestInterface::$canSetReporter(:39),$issueAttr(:112) andtlUser::$loginRegExp(lib/functions/tlUser.class.php:158, raised on everygetSecurityNotes()call viacheckForAdminDefaultPwd()). Not logged intoevents, but fatal on PHP 9.
-
lib/functions/configCheck.php— one call site (checkForBTSConnection($db)) plus a comment explaining why the handle is mandatory. -
CHANGELOG— one line under the 2.0.1[KEY BUGFIX]section.
Fixtures/harnesses (tmp/fixtures_1811.php, tmp/verify_1811.php,
tmp/TLU_Test_Cases.md) live under the git-ignored tmp/; they are recreated on
every run because the database is re-imported.
php tmp/fixtures_1811.php # creates project 7 / plan 8 / tracker 9003 (closed port)
php tmp/verify_1811.php # 8-case matrix -> "ALL CHECKS PASSED"
cat logs/config_check.txt # must contain "Connection to your Bug Tracking System has failed"
php tmp/fixtures_1811.php --resetBrowser: log in admin/admin → open a test plan's Execution Dashboard
(lib/execute/execDashboard.php?tplan_id=8&tproject_id=7) with
config_check_warning_frequence = 'ALWAYS' and config_check_warning_mode = 'FILE' in custom_config.inc.php, then check logs/config_check.txt.