11/*
2- * Copyright (c) 2003, 2018 , Oracle and/or its affiliates. All rights reserved.
2+ * Copyright (c) 2003, 2025 , Oracle and/or its affiliates. All rights reserved.
33 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44 *
55 * This code is free software; you can redistribute it and/or modify it
@@ -124,9 +124,12 @@ OSStatus ChangeListenerProc(AudioObjectID inObjectID, UInt32 inNumberAddresses,
124124 kAudioHardwarePropertyDevices , &size);
125125 if (err == noErr) {
126126 int count = size/sizeof (AudioDeviceID);
127- AudioDeviceID devices[count];
127+ AudioDeviceID *devices = (AudioDeviceID *) malloc (size);
128+ if (!devices) {
129+ break ;
130+ }
128131 err = GetAudioObjectProperty (kAudioObjectSystemObject , kAudioObjectPropertyScopeGlobal ,
129- kAudioHardwarePropertyDevices , count* sizeof (AudioDeviceID) , devices, 1 );
132+ kAudioHardwarePropertyDevices , size , devices, 1 );
130133 if (err == noErr) {
131134 bool found = false ;
132135 for (int j = 0 ; j < count; j++) {
@@ -139,6 +142,7 @@ OSStatus ChangeListenerProc(AudioObjectID inObjectID, UInt32 inNumberAddresses,
139142 invalid = true ;
140143 }
141144 }
145+ free (devices);
142146 }
143147 break ;
144148 case kAudioObjectPropertyOwnedObjects :
@@ -148,9 +152,12 @@ OSStatus ChangeListenerProc(AudioObjectID inObjectID, UInt32 inNumberAddresses,
148152 kAudioObjectPropertyOwnedObjects , &size);
149153 if (err == noErr) {
150154 int count = size / sizeof (AudioObjectID);
151- AudioObjectID controlIDs[count];
155+ AudioObjectID *controlIDs = (AudioObjectID *) malloc (size);
156+ if (!controlIDs) {
157+ break ;
158+ }
152159 err = GetAudioObjectProperty (mixer->deviceID , kAudioObjectPropertyScopeGlobal ,
153- kAudioObjectPropertyOwnedObjects , count * sizeof (AudioObjectID), & controlIDs, 1 );
160+ kAudioObjectPropertyOwnedObjects , size, controlIDs, 1 );
154161 if (err == noErr) {
155162 for (PortControl *ctrl = mixer->portControls ; ctrl != NULL ; ctrl = ctrl->next ) {
156163 for (int i = 0 ; i < ctrl->controlCount ; i++) {
@@ -168,6 +175,7 @@ OSStatus ChangeListenerProc(AudioObjectID inObjectID, UInt32 inNumberAddresses,
168175 }
169176 }
170177 }
178+ free (controlIDs);
171179 }
172180 }
173181 }
@@ -229,6 +237,9 @@ INT32 PORT_GetPortMixerDescription(INT32 mixerIndex, PortMixerDescription* mixer
229237void * PORT_Open (INT32 mixerIndex) {
230238 TRACE1 (" \n >>PORT_Open (mixerIndex=%d)\n " , (int )mixerIndex);
231239 PortMixer *mixer = (PortMixer *)calloc (1 , sizeof (PortMixer));
240+ if (!mixer) {
241+ return nullptr ;
242+ }
232243
233244 mixer->deviceID = deviceCache.GetDeviceID (mixerIndex);
234245 if (mixer->deviceID != 0 ) {
@@ -480,16 +491,20 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
480491 mixer->deviceControlCount = size / sizeof (AudioObjectID);
481492 TRACE1 (" PORT_GetControls: detected %d owned objects\n " , mixer->deviceControlCount );
482493
483- AudioObjectID controlIDs[mixer->deviceControlCount ];
494+ AudioObjectID *controlIDs = (AudioObjectID *) malloc (size);
495+ if (!controlIDs) {
496+ return ;
497+ }
484498
485499 err = GetAudioObjectProperty (mixer->deviceID , kAudioObjectPropertyScopeGlobal ,
486- kAudioObjectPropertyOwnedObjects , sizeof (controlIDs) , controlIDs, 1 );
500+ kAudioObjectPropertyOwnedObjects , size , controlIDs, 1 );
487501
488502 if (err) {
489503 OS_ERROR1 (err, " PORT_GetControls (portIndex = %d) get OwnedObject values" , portIndex);
490504 } else {
491505 mixer->deviceControls = (AudioControl *)calloc (mixer->deviceControlCount , sizeof (AudioControl));
492506 if (mixer->deviceControls == NULL ) {
507+ free (controlIDs);
493508 return ;
494509 }
495510
@@ -513,6 +528,7 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
513528 control->controlID , FourCC2Str (control->classID ), FourCC2Str (control->scope ), control->channel );
514529 }
515530 }
531+ free (controlIDs);
516532 }
517533 }
518534
@@ -524,10 +540,14 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
524540 int totalChannels = GetChannelCount (mixer->deviceID , port->scope == kAudioDevicePropertyScopeOutput ? 1 : 0 );
525541
526542 // collect volume and mute controls
527- AudioControl* volumeControls[totalChannels+1 ]; // 0 - for master channel
528- memset (&volumeControls, 0 , sizeof (AudioControl *) * (totalChannels+1 ));
529- AudioControl* muteControls[totalChannels+1 ]; // 0 - for master channel
530- memset (&muteControls, 0 , sizeof (AudioControl *) * (totalChannels+1 ));
543+ size_t totalAndMaster = totalChannels + 1 ; // 0 - for master channel
544+ AudioControl **volumeControls = (AudioControl **) calloc (totalAndMaster, sizeof (AudioControl *));
545+ AudioControl **muteControls = (AudioControl **) calloc (totalAndMaster, sizeof (AudioControl *));
546+ if (!volumeControls || !muteControls) {
547+ free (muteControls);
548+ free (volumeControls);
549+ return ;
550+ }
531551
532552 for (int i=0 ; i<mixer->deviceControlCount ; i++) {
533553 AudioControl *control = &mixer->deviceControls [i];
@@ -626,13 +646,17 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
626646 CFIndex length = CFStringGetLength (cfname) + 1 ;
627647 channelName = (char *)malloc (length);
628648 if (channelName == NULL ) {
649+ free (muteControls);
650+ free (volumeControls);
629651 return ;
630652 }
631653 CFStringGetCString (cfname, channelName, length, kCFStringEncodingUTF8 );
632654 CFRelease (cfname);
633655 } else {
634656 channelName = (char *)malloc (16 );
635657 if (channelName == NULL ) {
658+ free (muteControls);
659+ free (volumeControls);
636660 return ;
637661 }
638662 snprintf (channelName, 16 , " Ch %d" , ch);
@@ -657,7 +681,8 @@ void PORT_GetControls(void* id, INT32 portIndex, PortControlCreator* creator) {
657681 }
658682
659683 AddChangeListeners (mixer);
660-
684+ free (muteControls);
685+ free (volumeControls);
661686 TRACE1 (" <<PORT_GetControls (portIndex = %d)\n " , portIndex);
662687}
663688
@@ -772,28 +797,35 @@ float PORT_GetFloatValue(void* controlIDV) {
772797 PortControl *control = (PortControl *)controlIDV;
773798 Float32 result = 0 ;
774799
775- Float32 subVolumes[control->controlCount ];
800+ Float32 *subVolumes = (Float32 *) malloc (control->controlCount * sizeof (Float32));
801+ if (!subVolumes) {
802+ return DEFAULT_VOLUME_VALUE;
803+ }
776804 Float32 maxVolume;
777805
778806 switch (control->type ) {
779807 case PortControl::Volume:
780808 if (!TestPortControlValidity (control)) {
781- return DEFAULT_VOLUME_VALUE;
809+ result = DEFAULT_VOLUME_VALUE;
810+ break ;
782811 }
783812
784813 if (!GetPortControlVolumes (control, subVolumes, &maxVolume)) {
785- return DEFAULT_VOLUME_VALUE;
814+ result = DEFAULT_VOLUME_VALUE;
815+ break ;
786816 }
787817 result = maxVolume;
788818 break ;
789819 case PortControl::Balance:
790820 if (!TestPortControlValidity (control)) {
791- return DEFAULT_BALANCE_VALUE;
821+ result = DEFAULT_BALANCE_VALUE;
822+ break ;
792823 }
793824
794825 // balance control always has 2 volume controls
795826 if (!GetPortControlVolumes (control, subVolumes, &maxVolume)) {
796- return DEFAULT_VOLUME_VALUE;
827+ result = DEFAULT_VOLUME_VALUE;
828+ break ;
797829 }
798830 // calculate balance value
799831 if (subVolumes[0 ] > subVolumes[1 ]) {
@@ -806,9 +838,10 @@ float PORT_GetFloatValue(void* controlIDV) {
806838 break ;
807839 default :
808840 ERROR1 (" GetFloatValue requested for non-Float control (control-type == %d)\n " , control->type );
809- return 0 ;
841+ result = 0 ;
842+ break ;
810843 }
811-
844+ free (subVolumes);
812845 TRACE1 (" <<PORT_GetFloatValue = %f\n " , result);
813846 return result;
814847}
@@ -821,13 +854,16 @@ void PORT_SetFloatValue(void* controlIDV, float value) {
821854 return ;
822855 }
823856
824- Float32 subVolumes[control->controlCount ];
857+ Float32 *subVolumes = (Float32 *) malloc (sizeof (Float32) * control->controlCount );
858+ if (!subVolumes) {
859+ return ;
860+ }
825861 Float32 maxVolume;
826862
827863 switch (control->type ) {
828864 case PortControl::Volume:
829865 if (!GetPortControlVolumes (control, subVolumes, &maxVolume)) {
830- return ;
866+ break ;
831867 }
832868 // update the values
833869 if (maxVolume > 0.001 ) {
@@ -845,7 +881,7 @@ void PORT_SetFloatValue(void* controlIDV, float value) {
845881 case PortControl::Balance:
846882 // balance control always has 2 volume controls
847883 if (!GetPortControlVolumes (control, subVolumes, &maxVolume)) {
848- return ;
884+ break ;
849885 }
850886 // calculate new values
851887 if (value < 0 .0f ) {
@@ -861,8 +897,9 @@ void PORT_SetFloatValue(void* controlIDV, float value) {
861897 break ;
862898 default :
863899 ERROR1 (" PORT_SetFloatValue requested for non-Float control (control-type == %d)\n " , control->type );
864- return ;
900+ break ;
865901 }
902+ free (subVolumes);
866903}
867904
868905#endif // USE_PORTS
0 commit comments