Skip to content

Commit 182ee22

Browse files
committed
fix: Fix ioreg command output parsing on MacOSX
1 parent dc2bf92 commit 182ee22

File tree

3 files changed

+245
-42
lines changed

3 files changed

+245
-42
lines changed

Changes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ inventory:
2121
* fix #611: Wrong bios value as array on win32 bios when using WMI in proxmox vm
2222
* fix #609: Fix rustdesk remote management version analysis
2323
* fix #630: Enhanced support for linux on Raspberry Pi 3
24+
* Fix ioreg command output parsing on MacOSX to avoid Deep Recursion perl warning
2425

2526
remoteinventory:
2627
* Limit the number of attempts and reported errors when libssh2 fails but ssh command

lib/GLPI/Agent/Tools/MacOS.pm

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -316,48 +316,37 @@ sub getIODevices {
316316

317317
my $remain;
318318
sub _parseIORegAttributes {
319-
my ($string, $ref, $reflist) = @_;
319+
my ($string, $ref) = @_;
320320

321-
# Initialization when starting to parse a string
322-
unless ($ref) {
323-
$reflist = [];
324-
undef $remain;
325-
}
326-
327-
if ($string =~ /^{(.*)$/) {
328-
my $newref = {};
329-
push @{$reflist}, $ref if $ref;
330-
_parseIORegAttributes($1, $newref, $reflist);
331-
return $newref;
332-
} elsif ($string =~ /^\((.*)$/) {
333-
my $newref = [];
334-
push @{$reflist}, $ref if $ref;
335-
_parseIORegAttributes($1, $newref, $reflist);
336-
return $newref;
337-
}
338-
339-
if ($string =~ /^"([^"]+)"=(.*)$/) {
340-
my $key = $1;
341-
$ref->{$key} = _parseIORegAttributes($2, $ref, $reflist);
342-
} elsif ($string =~ /^"([^"]+)"(.*)$/ || $string =~ /^([^,}\)]+)([,}\)].*)$/) {
343-
$remain = $2;
344-
if (ref($ref) eq 'ARRAY') {
345-
push @{$ref}, $1;
346-
} else {
347-
return $1;
348-
}
349-
}
321+
$remain = $string;
350322

351-
if (defined($remain) && length($remain)) {
352-
if ($remain =~ /^([,}\)])(.*)$/) {
323+
while (defined($remain) && length($remain)) {
324+
if ($remain =~ /^{(.*)$/) {
325+
if (ref($ref) eq 'ARRAY') {
326+
push @{$ref}, _parseIORegAttributes($1, {});
327+
} else {
328+
return _parseIORegAttributes($1, {});
329+
}
330+
} elsif ($remain =~ /^\((.*)$/) {
331+
if (ref($ref) eq 'ARRAY') {
332+
push @{$ref}, _parseIORegAttributes($1, []);
333+
} else {
334+
return _parseIORegAttributes($1, []);
335+
}
336+
} elsif ($remain =~ /^"([^"]+)"=(.*)$/) {
337+
my $key = $1;
338+
$ref->{$key} = _parseIORegAttributes($2, $ref);
339+
} elsif ($remain =~ /^"([^"]+)"(.*)$/ || $remain =~ /^([^,}\)]+)([,}\)].*|)$/) {
353340
$remain = $2;
354-
if ($1 eq '}' || $1 eq ')') {
355-
my $parent = pop @{$reflist};
356-
push @{$parent}, $ref if ref($parent) eq 'ARRAY';
357-
$ref = $parent if $parent;
341+
if (ref($ref) eq 'ARRAY') {
342+
push @{$ref}, $1;
343+
} else {
344+
return $1;
358345
}
346+
} elsif ($remain =~ /^([,}\)])(.*)$/) {
347+
$remain = $2;
348+
last if $1 eq '}' || $1 eq ')';
359349
}
360-
_parseIORegAttributes($remain, $ref, $reflist) if length($remain);
361350
}
362351

363352
return $ref;

t/agent/tools/macos.t

Lines changed: 218 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use Test::Deep;
1010
use Test::More;
1111
use English;
1212
use UNIVERSAL::require;
13+
use Data::Dumper;
1314

1415
use GLPI::Agent::Tools::MacOS;
1516
use GLPI::Agent::Task::Inventory::MacOS::Softwares;
@@ -3410,6 +3411,212 @@ my @ioreg_tests = (
34103411
}
34113412
],
34123413
},
3414+
{
3415+
file => 'IOPlatformExpertDevice-2',
3416+
class => 'IOPlatformExpertDevice',
3417+
results => [
3418+
{
3419+
'serial-number' => '46564838000000000000000000433032514d33465346564838000000000000000000000000000000000000',
3420+
'clock-frequency' => '00e1f505',
3421+
'board-id' => 'Mac-E43C1C25D4880AD6',
3422+
'target-type' => 'Mac',
3423+
'IOBusyInterest' => 'IOCommand is not serializable',
3424+
'IOPlatformSystemSleepPolicy' => '534c505402001300841e120004000000001400000004000006000000000000000f250000000000000000400000004000000010000000100007000000000000000f25000000000000841e120004000000001800000008000005000000000000000f25000000000000841e120004000000081000000800000005000000000000000f250000000000002000000020000000000000000000000005000000000000000f2500000000000008000000080000000000000000000000060000000000000000010000010000000000040000000400000000000000000005000000000000000f250000000000000000010000000100000000000000000006000000000000000001000000000000c416000000000000080000000800000005000000000000000f25000000000000c416100000001000204000002040000007000000080000000f3d000000000000c416000000000000200000002000000005000000000000000f25000000000000d416000010000000000000000000000005000000000000000f25000000000000c41e120044000000061000000600000007000000020000000f3d000000000000841e120004000000001000000000000007000000020000000f3d000000000000c41600000000000000c0000000c0000007000000080000000f3d000000000000c416000000000000088000000880000005000000000000000f25000000000000c416000000000000000000000000000007000000010000000f3d0000000000004000000040000000060000000600000007000000000000000f350000000000000000000000000000000000000000000007000000000000000f35000000000000',
3425+
'IOPlatformSerialNumber' => 'C02QM3FSFVH8',
3426+
'compatible' => 'MacBookPro12,1',
3427+
'IOPolledInterface' => 'SMCPolledInterface is not serializable',
3428+
'manufacturer' => 'Apple Inc.',
3429+
'IOPlatformUUID' => 'CE3A2773-AF9E-515B-918B-5EE5C09372D7',
3430+
'platform-feature' => '0200000000000000',
3431+
'model' => 'MacBookPro12,1',
3432+
'system-type' => '02',
3433+
'product-name' => 'MacBookPro12,1',
3434+
'version' => '1.0',
3435+
'name' => '/'
3436+
}
3437+
],
3438+
},
3439+
{
3440+
file => 'AppleBacklightDisplay',
3441+
class => 'AppleBacklightDisplay',
3442+
results => [
3443+
{
3444+
'IOProbeScore' => 3000,
3445+
'IODisplayAttributes' => {
3446+
'IODisplayAttributes' => '<676174760000000073676c6604000000726c6f630100000063706220020000006364670080808000676c666400000000>'
3447+
},
3448+
'IODisplayGUID' => '436849163854938112',
3449+
'IOProviderClass' => 'IODisplayConnect',
3450+
'CFBundleIdentifierKernel' => 'com.apple.iokit.IOGraphicsFamily',
3451+
'IODisplayConnectFlags' => '00080000',
3452+
'IOPowerManagement' => {
3453+
'CurrentPowerState' => 3,
3454+
'MaxPowerState' => 3,
3455+
'CapabilityFlags' => 49152
3456+
},
3457+
'IODisplayEDID' => '00ffffffffffff0006102aa0000000000a180104a51d1278026fb1a7554c9e250c505400000001010101010101010101010101010101e26800a0a0402e60302036001eb31000001a000000fc00436f6c6f72204c43440a2020200000001000000000000000000000000000000000001000000000000000000000000000000075',
3458+
'IODisplayPrefsKey' => 'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@0/display0/AppleBacklightDisplay-610-a02a',
3459+
'DisplayVendorID' => 1552,
3460+
'DisplayProductID' => 41002,
3461+
'IOMatchCategory' => 'IODefaultMatchCategory',
3462+
'DisplaySerialNumber' => 0,
3463+
'IOClass' => 'AppleBacklightDisplay',
3464+
'CFBundleIdentifier' => 'com.apple.iokit.IOGraphicsFamily',
3465+
'IODisplayParameters' => {
3466+
'rgsc' => {
3467+
'max' => 65536,
3468+
'min' => 0,
3469+
'value' => 65536
3470+
},
3471+
'ggsc' => {
3472+
'value' => 65536,
3473+
'max' => 65536,
3474+
'min' => 0
3475+
},
3476+
'brightness' => {
3477+
'max' => 1024,
3478+
'min' => 0,
3479+
'value' => 575
3480+
},
3481+
'bklt' => {
3482+
'value' => 378,
3483+
'min' => 0,
3484+
'max' => 1388
3485+
},
3486+
'fade-style' => {
3487+
'value' => 0,
3488+
'min' => 0,
3489+
'max' => 10
3490+
},
3491+
'vblm' => {
3492+
'max' => 196608,
3493+
'min' => 0,
3494+
'value' => 65536
3495+
},
3496+
'brightness-probe' => {
3497+
'max' => 1024,
3498+
'min' => 0,
3499+
'value' => 575
3500+
},
3501+
'ownr' => '4294968317',
3502+
'fade-time2' => {
3503+
'value' => 4000,
3504+
'max' => 10000,
3505+
'min' => 0
3506+
},
3507+
'usable-linear-brightness' => {
3508+
'max' => 1385,
3509+
'min' => 23,
3510+
'value' => 315
3511+
},
3512+
'fade-time3' => {
3513+
'min' => 0,
3514+
'max' => 10000,
3515+
'value' => 500
3516+
},
3517+
'linear-brightness-probe' => {
3518+
'value' => 315,
3519+
'min' => 0,
3520+
'max' => 1385
3521+
},
3522+
'linear-brightness' => {
3523+
'min' => 0,
3524+
'max' => 1385,
3525+
'value' => 315
3526+
},
3527+
'fade-time1' => {
3528+
'max' => 10000,
3529+
'min' => 0,
3530+
'value' => 500
3531+
},
3532+
'dsyp' => {
3533+
'value' => 2,
3534+
'max' => 2,
3535+
'min' => 0
3536+
},
3537+
'bgsc' => {
3538+
'max' => 65536,
3539+
'min' => 0,
3540+
'value' => 65536
3541+
},
3542+
'brightness-fade' => {
3543+
'min' => 0,
3544+
'max' => 1023,
3545+
'value' => 0
3546+
},
3547+
'commit' => {
3548+
'reg' => 0
3549+
}
3550+
}
3551+
}
3552+
],
3553+
},
3554+
{
3555+
file => 'AppleDisplay',
3556+
class => 'AppleDisplay',
3557+
results => [
3558+
{
3559+
'IODisplayPrefsKey' => 'IOService:/AppleACPIPlatformExpert/PCI0@0/AppleACPIPCI/IGPU@2/AppleIntelFramebuffer@2/display0/AppleDisplay-10ac-4023',
3560+
'DisplaySerialNumber' => 843535699,
3561+
'DisplayVendorID' => 4268,
3562+
'IODisplayConnectFlags' => '00000000',
3563+
'IODisplayEDID' => '00ffffffffffff0010ac2340535547321f1201036a221b78ee8d45a5564b9b26135054a54b008180714f010101010101010101010101302a009851002a4030701300520e1100001e000000ff004338393148383752324755530a000000fc0044454c4c203137303846500a20000000fd00384c1e510e000a202020202020009b',
3564+
'IOMatchCategory' => 'IODefaultMatchCategory',
3565+
'DisplayProductID' => 16419,
3566+
'IOPowerManagement' => {
3567+
'MaxPowerState' => 3,
3568+
'CapabilityFlags' => 49152,
3569+
'CurrentPowerState' => 3
3570+
},
3571+
'IODisplayParameters' => {
3572+
'cyuv' => {
3573+
'min' => 0,
3574+
'max' => 268435456,
3575+
'value' => 268435456
3576+
},
3577+
'vblm' => {
3578+
'max' => 196608,
3579+
'value' => 65536,
3580+
'min' => 0
3581+
},
3582+
'rgsc' => {
3583+
'max' => 65536,
3584+
'value' => 65536,
3585+
'min' => 0
3586+
},
3587+
'cmod' => {
3588+
'max' => 4096,
3589+
'value' => 1,
3590+
'min' => 0
3591+
},
3592+
'ggsc' => {
3593+
'max' => 65536,
3594+
'value' => 65536,
3595+
'min' => 0
3596+
},
3597+
'colr' => {
3598+
'min' => 0,
3599+
'value' => 257,
3600+
'max' => '18446744073709551615'
3601+
},
3602+
'bgsc' => {
3603+
'min' => 0,
3604+
'max' => 65536,
3605+
'value' => 65536
3606+
},
3607+
'ownr' => '4294968319'
3608+
},
3609+
'IOProbeScore' => 2000,
3610+
'CFBundleIdentifier' => 'com.apple.iokit.IOGraphicsFamily',
3611+
'IOClass' => 'AppleDisplay',
3612+
'IODisplayAttributes' => {
3613+
'IODisplayAttributes' => '<676174760000000073676c6600000000726c6f630100000063706220000000006364670080808000676c666400000000>'
3614+
},
3615+
'CFBundleIdentifierKernel' => 'com.apple.iokit.IOGraphicsFamily',
3616+
'IOProviderClass' => 'IODisplayConnect'
3617+
}
3618+
],
3619+
},
34133620
{
34143621
file => 'AppleCLCD2',
34153622
class => 'AppleCLCD2',
@@ -5974,17 +6181,23 @@ foreach my $test (keys %system_profiler_tests) {
59746181
cmp_deeply($infos, $system_profiler_tests{$test}, "$test system profiler parsing");
59756182
}
59766183

6184+
foreach my $test (@ioregparsing) {
6185+
my $parsed = GLPI::Agent::Tools::MacOS::_parseIORegAttributes($test->{value});
6186+
cmp_deeply($parsed, $test->{expect}, "$test->{name} ioreg parsing");
6187+
}
6188+
59776189
foreach my $test (@ioreg_tests) {
59786190
my $file = "resources/macos/ioreg/$test->{file}";
59796191
my @devices = getIODevices(file => $file, class => $test->{class});
6192+
# Dump found result when still not integrated in test file
6193+
unless ($test->{results} && @{$test->{results}}) {
6194+
my $dumper = Data::Dumper->new(\@devices)->Useperl(1)->Indent(1)->Pad(" ");
6195+
$dumper->{xpad} = " ";
6196+
print STDERR "CURRENT RESULTS: ", $dumper->Dump();
6197+
}
59806198
cmp_deeply(\@devices, $test->{results}, "$test->{file} ioreg parsing");
59816199
}
59826200

5983-
foreach my $test (@ioregparsing) {
5984-
my $parsed = GLPI::Agent::Tools::MacOS::_parseIORegAttributes($test->{value});
5985-
cmp_deeply($parsed, $test->{expect}, "$test->{name} ioreg parsing");
5986-
}
5987-
59886201
foreach my $test (keys(%xmlparsing)) {
59896202
my $type = 'SPApplicationsDataType';
59906203

0 commit comments

Comments
 (0)