Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 92 additions & 57 deletions modules/kvm-helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function getUsers()
var res, i, uu = {};
require('user-sessions').Current(function (u) { res = u; });

for (i in res)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 getUsers() references undeclared/leaked global 'i' variable via for..in without var

In getUsers(), changed both for (i in res) and for (i in spawnable) to for (var i in res) and for (var i in spawnable) respectively, declaring the loop variable locally instead of leaking a global i.

🤖 Prompt for AI agents
In modules/kvm-helper.js around line 8, review and complete this code-review fix: getUsers() references undeclared/leaked global 'i' variable via for..in without var.
What the draft fix changed: In `getUsers()`, changed both `for (i in res)` and `for (i in spawnable)` to `for (var i in res)` and `for (var i in spawnable)` respectively, declaring the loop variable locally instead of leaking a global `i`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

for (var i in res)
{
if (process.platform != 'win32') { res[i].SessionId = res[i].uid; }
if (res[i].State == 'Active' || res[i].State == 'Connected') { uu[process.platform == 'win32' ? res[i].SessionId : res[i].uid] = res[i]; }
Expand All @@ -14,7 +14,7 @@ function getUsers()
if (process.platform == 'linux')
{
var spawnable = this.loginUids();
for (i in spawnable)
for (var i in spawnable)
{
if (uu[spawnable[i].uid] == null)
{
Expand Down Expand Up @@ -86,9 +86,14 @@ if (process.platform == 'linux')
var terminal = childProcess.execFile('/bin/sh', options);

terminal.stdout.on('data', function (c) { console.info1(c.toString()); });
terminal.stdin.write('su ' + username + '\n');
terminal.stdin.write('xvfb-run -n 99 -a ' + startDM + ' &\n');
terminal.stdin.write('exit\nexit\n');
try
{
terminal.stdin.write('su ' + username + '\n');
terminal.stdin.write('xvfb-run -n 99 -a ' + startDM + ' &\n');
terminal.stdin.write('exit\nexit\n');
}
catch (z)
{ }
terminal.waitExit();
return (uid);
}
Expand All @@ -108,7 +113,7 @@ if (process.platform == 'linux')
{
var lids = module.exports.allowed
var uu = {};
for (i in lids)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🟠 loginUids() also leaks undeclared global loop variable 'i'

In loginUids(), changed for (i in lids) to for (var i in lids), declaring the loop variable locally to match the fix applied to getUsers().

🤖 Prompt for AI agents
In modules/kvm-helper.js around line 111, review and complete this code-review fix: loginUids() also leaks undeclared global loop variable 'i'.
What the draft fix changed: In `loginUids()`, changed `for (i in lids)` to `for (var i in lids)`, declaring the loop variable locally to match the fix applied to `getUsers()`.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟢 90 high — react 👍/👎 to teach the reviewer

for (var i in lids)
{
try
{
Expand All @@ -129,25 +134,30 @@ if (process.platform == 'linux')
{
var child = require('child_process').execFile('/bin/sh', ['sh']);

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🦩 🔴 child.stdin.write() calls not wrapped in try/catch, unlike ws.send() convention elsewhere

Wrapped every child.stdin.write(...) / terminal.stdin.write(...) call sequence in try/catch blocks across spawnVirtualSession, waylandStatus (both gdm/gdm3 branches), disableWayland (both branches), and enableWayland (both branches) in modules/kvm-helper.js. Each block of consecutive writes to a given child process is wrapped together (rather than each call individually) to keep the change minimal while ensuring an exception from a closed/broken stdin pipe is caught rather than propagating unhandled; child.waitExit() is still called afterward in all cases to preserve existing control flow.

🤖 Prompt for AI agents
In modules/kvm-helper.js around line 130, review and complete this code-review fix: child.stdin.write() calls not wrapped in try/catch, unlike ws.send() convention elsewhere.
What the draft fix changed: Wrapped every `child.stdin.write(...)` / `terminal.stdin.write(...)` call sequence in try/catch blocks across `spawnVirtualSession`, `waylandStatus` (both gdm/gdm3 branches), `disableWayland` (both branches), and `enableWayland` (both branches) in `modules/kvm-helper.js`. Each block of consecutive writes to a given child process is wrapped together (rather than each call individually) to keep the change minimal while ensuring an exception from a closed/broken stdin pipe is caught rather than propagating unhandled; `child.waitExit()` is still called afterward in all cases to preserve existing control flow.
Verify the change is correct and complete; do not refactor unrelated code.

fix confidence: 🟡 75 medium — react 👍/👎 to teach the reviewer

child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stdin.write("cat /etc/gdm/custom.conf | grep WaylandEnable= | tr '\\n' '`' | awk -F'`' '");
child.stdin.write('{');
child.stdin.write(' wayland=1;');
child.stdin.write(' for(n=1;n<NF;++n) ');
child.stdin.write(' {');
child.stdin.write(' if($n~/^#/) { continue; }')
child.stdin.write(' gsub(/ /, "", $n);');
child.stdin.write(' if($n~/^WaylandEnable=/)');
child.stdin.write(' {');
child.stdin.write(' split($n, dummy, "WaylandEnable=");');
child.stdin.write(' if(dummy[2]=="false")');
child.stdin.write(' {');
child.stdin.write(' wayland=0;');
child.stdin.write(' }');
child.stdin.write(' break;');
child.stdin.write(' }');
child.stdin.write(' }');
child.stdin.write(' print wayland;');
child.stdin.write("}'\nexit\n");
try
{
child.stdin.write("cat /etc/gdm/custom.conf | grep WaylandEnable= | tr '\\n' '`' | awk -F'`' '");
child.stdin.write('{');
child.stdin.write(' wayland=1;');
child.stdin.write(' for(n=1;n<NF;++n) ');
child.stdin.write(' {');
child.stdin.write(' if($n~/^#/) { continue; }')
child.stdin.write(' gsub(/ /, "", $n);');
child.stdin.write(' if($n~/^WaylandEnable=/)');
child.stdin.write(' {');
child.stdin.write(' split($n, dummy, "WaylandEnable=");');
child.stdin.write(' if(dummy[2]=="false")');
child.stdin.write(' {');
child.stdin.write(' wayland=0;');
child.stdin.write(' }');
child.stdin.write(' break;');
child.stdin.write(' }');
child.stdin.write(' }');
child.stdin.write(' print wayland;');
child.stdin.write("}'\nexit\n");
}
catch (z)
{ }
child.waitExit();
if (child.stdout.str.trim() == '0')
{
Expand All @@ -158,25 +168,30 @@ if (process.platform == 'linux')
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stdin.write("cat /etc/gdm3/custom.conf | grep WaylandEnable= | tr '\\n' '`' | awk -F'`' '");
child.stdin.write('{');
child.stdin.write(' wayland=1;');
child.stdin.write(' for(n=1;n<NF;++n) ');
child.stdin.write(' {');
child.stdin.write(' if($n~/^#/) { continue; }')
child.stdin.write(' gsub(/ /, "", $n);');
child.stdin.write(' if($n~/^WaylandEnable=/)');
child.stdin.write(' {');
child.stdin.write(' split($n, dummy, "WaylandEnable=");');
child.stdin.write(' if(dummy[2]=="false")');
child.stdin.write(' {');
child.stdin.write(' wayland=0;');
child.stdin.write(' }');
child.stdin.write(' break;');
child.stdin.write(' }');
child.stdin.write(' }');
child.stdin.write(' print wayland;');
child.stdin.write("}'\nexit\n");
try
{
child.stdin.write("cat /etc/gdm3/custom.conf | grep WaylandEnable= | tr '\\n' '`' | awk -F'`' '");
child.stdin.write('{');
child.stdin.write(' wayland=1;');
child.stdin.write(' for(n=1;n<NF;++n) ');
child.stdin.write(' {');
child.stdin.write(' if($n~/^#/) { continue; }')
child.stdin.write(' gsub(/ /, "", $n);');
child.stdin.write(' if($n~/^WaylandEnable=/)');
child.stdin.write(' {');
child.stdin.write(' split($n, dummy, "WaylandEnable=");');
child.stdin.write(' if(dummy[2]=="false")');
child.stdin.write(' {');
child.stdin.write(' wayland=0;');
child.stdin.write(' }');
child.stdin.write(' break;');
child.stdin.write(' }');
child.stdin.write(' }');
child.stdin.write(' print wayland;');
child.stdin.write("}'\nexit\n");
}
catch (z)
{ }
child.waitExit();
if (child.stdout.str.trim() == '0')
{
Expand All @@ -194,18 +209,28 @@ if (process.platform == 'linux')
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stdin.write('sed "s/#WaylandEnable=false/WaylandEnable=false/g" /etc/gdm/custom.conf > /etc/gdm/custom_2.conf\n');
child.stdin.write("mv /etc/gdm/custom_2.conf /etc/gdm/custom.conf\n");
child.stdin.write("\nexit\n");
try
{
child.stdin.write('sed "s/#WaylandEnable=false/WaylandEnable=false/g" /etc/gdm/custom.conf > /etc/gdm/custom_2.conf\n');
child.stdin.write("mv /etc/gdm/custom_2.conf /etc/gdm/custom.conf\n");
child.stdin.write("\nexit\n");
}
catch (z)
{ }
child.waitExit();
}
if (require('fs').existsSync('/etc/gdm3/custom.conf'))
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stdin.write('sed "s/#WaylandEnable=false/WaylandEnable=false/g" /etc/gdm3/custom.conf > /etc/gdm3/custom_2.conf\n');
child.stdin.write("mv /etc/gdm3/custom_2.conf /etc/gdm3/custom.conf\n");
child.stdin.write("\nexit\n");
try
{
child.stdin.write('sed "s/#WaylandEnable=false/WaylandEnable=false/g" /etc/gdm3/custom.conf > /etc/gdm3/custom_2.conf\n');
child.stdin.write("mv /etc/gdm3/custom_2.conf /etc/gdm3/custom.conf\n");
child.stdin.write("\nexit\n");
}
catch (z)
{ }
child.waitExit();
}
}
Expand All @@ -218,18 +243,28 @@ if (process.platform == 'linux')
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stdin.write('sed "s/WaylandEnable=false/#WaylandEnable=false/g" /etc/gdm/custom.conf > /etc/gdm/custom_2.conf\n');
child.stdin.write("mv /etc/gdm/custom_2.conf /etc/gdm/custom.conf\n");
child.stdin.write("\nexit\n");
try
{
child.stdin.write('sed "s/WaylandEnable=false/#WaylandEnable=false/g" /etc/gdm/custom.conf > /etc/gdm/custom_2.conf\n');
child.stdin.write("mv /etc/gdm/custom_2.conf /etc/gdm/custom.conf\n");
child.stdin.write("\nexit\n");
}
catch (z)
{ }
child.waitExit();
}
if (require('fs').existsSync('/etc/gdm3/custom.conf'))
{
var child = require('child_process').execFile('/bin/sh', ['sh']);
child.stdout.str = ''; child.stdout.on('data', function (c) { this.str += c.toString(); });
child.stdin.write('sed "s/WaylandEnable=false/#WaylandEnable=false/g" /etc/gdm3/custom.conf > /etc/gdm3/custom_2.conf\n');
child.stdin.write("mv /etc/gdm3/custom_2.conf /etc/gdm3/custom.conf\n");
child.stdin.write("\nexit\n");
try
{
child.stdin.write('sed "s/WaylandEnable=false/#WaylandEnable=false/g" /etc/gdm3/custom.conf > /etc/gdm3/custom_2.conf\n');
child.stdin.write("mv /etc/gdm3/custom_2.conf /etc/gdm3/custom.conf\n");
child.stdin.write("\nexit\n");
}
catch (z)
{ }
child.waitExit();
}
}
Expand Down Expand Up @@ -262,4 +297,4 @@ else
users: getUsers,
allowed: allowedUIDs
}
}
}