bugfix issue 1879 getreqmgrsystemcfgtemplate bare url e warning - sebiboga/testlink-upgraded GitHub Wiki
Bug fix — Issue #1879: lib/ajax/getreqmgrsystemcfgtemplate.php raised E_WARNING Undefined array key "type" on a bare request and wrote an Event Viewer row
| Issue | #1879 |
| Type | bug (legacy PHP 8 diagnostic / Event Viewer noise) |
| Fix commit |
6299f8209 — lib/ajax/getreqmgrsystemcfgtemplate.php (1 line) |
| Severity | minor — one spurious Event Viewer row per bare request; the HTTP answer is already sane |
| Status | FIXED, verified error-free |
A request to lib/ajax/getreqmgrsystemcfgtemplate.php without a type
parameter answered 200 {"sucess":true,"cfg":"…"} — a perfectly sane body — but
also logged:
log_level 2
E_WARNING
Undefined array key "type" - in .../lib/ajax/getreqmgrsystemcfgtemplate.php - Line 23
into the events table, i.e. into the Event Viewer. Every bare request repeated
it. Discovered while regression-testing #1716 (which does not cause it — that
issue's diff touches only locale/*/strings.txt).
Pre-fix measurement on this run (fresh DB, baseline MAX(events.id) = 3):
$ curl -s -b cookies "http://localhost:8082/lib/ajax/getreqmgrsystemcfgtemplate.php"
{"sucess":true,"cfg":"LOCALIZE: reqmgrsystem_invalid_type"} [200]
$ mysql ... -e "SELECT id,log_level,description FROM events WHERE id > 3;"
4 2 E_WARNING\nUndefined array key "type" - in .../getreqmgrsystemcfgtemplate.php - Line 23
- TestLink 2.0.1, PHP built-in server at
http://localhost:8082, MariaDB127.0.0.1:3306(testlink/testlink), database freshly imported, loginadmin/admin. - Branch
fix/issue-1879-bare-url-type-warningoffa6973d54b. - Login via the HTML form (
tl_login/tl_password— the 2.0.1 field names), then:
curl -s -c c.txt -b c.txt -X POST http://localhost:8082/login.php \
-d "tl_login=admin&tl_password=admin&submit=Login"
mysql ... -e "SELECT COALESCE(MAX(id),0) FROM events;" # 3
curl -s -b c.txt "http://localhost:8082/lib/ajax/getreqmgrsystemcfgtemplate.php"
mysql ... -e "SELECT id,log_level,description FROM events WHERE id > 3;" # the E_WARNING row| # | hop | location |
|---|---|---|
| 1 |
$type = intval($_REQUEST['type']); reads a superglobal key that need not exist |
lib/ajax/getreqmgrsystemcfgtemplate.php:23 |
| 2 | on PHP 8 an absent key is E_WARNING "Undefined array key", not a silent null
|
PHP 8 semantics |
| 3 |
config.inc.php + common.php (loaded at :18-19) install TestLink's error handler before line 23 runs, so the warning is captured |
testlinkInitPage($db) :20
|
| 4 | the handler writes it to events (log_level 2) — the visible symptom |
watchPHPErrors |
| 5 |
intval(null) === 0, which is not a key of tlReqMgrSystem::getTypes() (single entry 1, lib/functions/tlReqMgrSystem.class.php:33), so the else branch already answers the correct "invalid type" message |
:26, :44-47
|
The behaviour was always correct; only the diagnostic was spurious. That is why the response body is byte-identical before and after the fix.
Why it is a missing port, not a regression: the two BFF twins written for
#1625/#1626 already guard the same read — api/reqmgrsystems/index.php:166
($_GET['type'] ?? 0) and api/reqmgrsystemedit/index.php:292
(bffQueryInt('type')) — and the other lib/ajax/ readers guard the same way
(getreqlog.php:38-42, getreqspeclog.php:38-42 isset() ternaries;
gettestcasesummary.php:120-143 isset() && short-circuits). This legacy
1.9.6 line (@since 1.9.6) was the only one left unguarded.
Blast radius: grep -rn "\$_REQUEST\['type'\]" lib/ → exactly 1 hit
(this file). Its only callers are the two retired
gui/templates/{dashio,tl-classic}/reqmgrsystems/reqMgrSystemEdit.tpl:42
displayCfgExample() calls — since #1727 reqMgrSystemEdit.php is a redirect
shim and the modern editor goes through api/reqmgrsystemedit/index.php?action=cfg_template
— and those callers always send type, so normal UI traffic never triggered the
warning; it came from bare/manual/edge requests. Hence minor.
--- a/lib/ajax/getreqmgrsystemcfgtemplate.php
+++ b/lib/ajax/getreqmgrsystemcfgtemplate.php
@@ -20,7 +20,7 @@
testlinkInitPage($db);
$info = array('sucess' => true, 'cfg' => '');
-$type = intval($_REQUEST['type']);
+$type = intval($_REQUEST['type'] ?? 0);
$mgr = new tlReqMgrSystem($db);0 is exactly the value the endpoint already produced for a missing key
(intval(null)), so every downstream branch, sprintf and response body stays
byte-identical — only the diagnostic disappears.
Alternatives rejected
-
isset()ternary (isset($_REQUEST['type']) ? intval($_REQUEST['type']) : 0) — identical semantics, more characters, and the house style for this exact guard is the?? 0already used by the BFF twin atapi/reqmgrsystems/index.php:166. -
@intval(...)/ raisingerror_reporting— hides every future diagnostic in the same code, including real bugs (explicitly rejected in #1626's docs too). - Answering
400for a missingtype(what the BFF does) — would change the legacy contract the.tplcallers rely on; out of scope for a minimal fix.


php -l clean. Five-request matrix post-fix, events baselined at id = 5:
| # | Request | Body | HTTP | New events rows |
|---|---|---|---|---|
| 1 | bare (no type) |
LOCALIZE: reqmgrsystem_invalid_type |
200 | 0 |
| 2 | ?type= |
same as pre-fix | 200 | 0 |
| 3 | ?type=99 |
same as pre-fix | 200 | 0 |
| 4 | ?type=1 |
LOCALIZE: reqmgrsystem_interface_not_implemented |
200 |
0 (log_level 32 LOCALIZE row only = #1716) |
| 5 | ?type=abc |
LOCALIZE: reqmgrsystem_invalid_type |
200 | 0 |
Bodies are byte-identical to the pre-fix capture for every variant; the only
difference in the whole matrix is the absence of the E_WARNING row.
Browser regression (fresh fixture reqmgrsystems row id=1 'Contour Demo' type=1):
logged in, opened gui/templates/reqmgrsystems/reqMgrSystemEdit.html, clicked
show configuration example → the BFF rendered the documented #1625/#1626
degradation Interface contoursoapInterface not implemented, console clean
(only the pre-existing "No label associated with a form field" a11y lint),
events gained 0 Error/Warning rows.
Event Viewer at the end of the run: log_level counts 1 → 0, 2 → 2 (both
rows are pre-fix baselines id=2/id=4), 16 → 2 (audit logins),
32 → 3 (#1716 LOCALIZE rows). No new Error/Warning attributable to the fix.
Regression suite: Regression — Issue #1879 in tmp/TLU_Test_Cases.md,
5/5 PASS; gate TLU_REQUIRE_SUITE="Issue #1879" bash ai/verify_test_suites.sh
→ 7 PASS / 0 FAIL, exit 0.
-
lib/ajax/getreqmgrsystemcfgtemplate.php— the one guarded read. -
CHANGELOG— one dated 2.0.1 line. -
tmp/TLU_Test_Cases.md— the numbered regression suite (git-ignored, appended).
No i18n bundle, no template, no BFF file, no DB change.
-
#1716 (open) — both
lang_get()keys used by this endpoint (reqmgrsystem_interface_not_implemented,reqmgrsystem_invalid_type) exist in no locale file, so the endpoint answers the literalLOCALIZE: <key>marker and adds alog_level 32row per request. Visible in every row of the table above; deliberately left alone (one bug per run).
php -l lib/ajax/getreqmgrsystemcfgtemplate.php
# login, then:
curl -s -b c.txt "http://localhost:8082/lib/ajax/getreqmgrsystemcfgtemplate.php"
mysql -h 127.0.0.1 -utestlink -ptestlink testlink \
-e "SELECT id,log_level,description FROM events WHERE id > <baseline>; "
# -> no log_level 2 row, and the JSON body is unchangedBrowser: log in admin/admin → Requirement Management System list → edit a
row → show configuration example → no new Event Viewer Error/Warning.