Bug 845928

Summary: Ops.is() does not check nested data types [was: Yast sound module crashes on deleting soundcard config]
Product: [openSUSE] openSUSE 13.1 Reporter: Forgotten User 1LnIo8z5Ac <forgotten_1LnIo8z5Ac>
Component: YaST2Assignee: Ladislav Slezák <lslezak>
Status: RESOLVED FIXED QA Contact: Jiri Srain <jsrain>
Severity: Major    
Priority: P2 - High CC: lslezak
Version: RC 1   
Target Milestone: RC 2   
Hardware: x86-64   
OS: SUSE Other   
Whiteboard:
Found By: --- Services Priority:
Business Priority: Blocker: ---
Marketing QA Status: --- IT Deployment: ---
Attachments: y2logs

Description Forgotten User 1LnIo8z5Ac 2013-10-15 09:13:58 UTC
User-Agent:       Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0

The Yast Sound-configuration crashes on deleting the secondary sound card configuration (ATI Technologies Inc.). After reopening sound-config the sound card config is still there.

Reproducible: Always

Steps to Reproduce:
1.Start Yast Sound-configuration
2.Delete secondary sound card configuration (ATI Technologies Inc.)
3.Confirm to delete
4.Sound-config crashes (window disapears)
5.reopen sound-config - sound card config is still there.
Actual Results:  
Sound card settings still there

Expected Results:  
Sound card settings deleted

With the primary intel ICH10 SoundCard this does NOT happen.
Comment 1 Ye Yuan 2013-10-17 06:12:19 UTC
Hi thomas, pls attach y2log following:
http://en.opensuse.org/openSUSE:Bugreport_YaST
Thanks!
Comment 2 Ladislav Slezák 2013-10-17 08:44:27 UTC
I found the problem here:

  https://github.com/yast/yast-ruby-bindings/blob/master/src/ruby/yast/ops.rb#L322

Ops.is() does not check for the nested types, which is essential in the sound module here:

  https://github.com/yast/yast-sound/blob/master/src/include/sound/routines.rb#L450

The code is evaluated to true

  Ops.is([[["Master", 74, false]]], "list <list <map>>") => true 

which results in broken vol_settings list (it is converted to something like [[["", 0, true]]] which causes crash when constructing the SCR path later:

  Client call failed with Invalid path '.audio.alsa.cards.0.channels..volume'


The workaround could we replacing

  Ops.is(vol_settings, "list <list <map>>")

by something like 

  vol_settings[0].is_a?(Array) && vol_settings[0][0].is_a?(Hash)

but this problem can be present in other Yast modules as well... :-(
Comment 3 Ladislav Slezák 2013-10-17 08:57:52 UTC
The other possibly affected places:

./autoinstallation/src/include/autoinstall/tree.rb:56:        elsif Ops.is(e, "list <term>")
./backup/src/modules/Backup.rb:1578:      if Ops.is(read_dir_list, "list <string>")
./backup/src/modules/Backup.rb:1584:      elsif Ops.is(read_dir_list, "list <term>")
./registration/src/clients/inst_suse_register.rb:1681:          Ops.is(Ops.get_list(options, :repos, []), "list <string>") &&
./yast2/library/commandline/src/modules/CommandLine.rb:606:      elsif Ops.is(commandhelp, "list <string>")
./yast2/library/commandline/src/modules/CommandLine.rb:671:          elsif Ops.is(opthelp, "map <string, string>")
./yast2/library/commandline/src/modules/CommandLine.rb:681:          elsif Ops.is(opthelp, "list <string>")
./yast2/library/commandline/src/modules/CommandLine.rb:724:        elsif Ops.is(example, "list <string>")
./yast2/library/commandline/src/modules/CommandLine.rb:846:        elsif Ops.is(Ops.get(desc, "help"), "list <string>")
./yast2/library/commandline/src/modules/CommandLine.rb:1001:          elsif Ops.is(help_value, "list <string>")
./yast2/library/cwm/src/modules/CWM.rb:228:          success = Ops.is(value, "list <list <string>>")
./yast2/library/cwm/src/modules/CWM.rb:230:          success = Ops.is(value, "boolean (string, map <string, any>)")
./yast2/library/cwm/src/modules/CWMTsigKeys.rb:292:            Ops.is(Ops.get(widget, "list_used_keys"), "list <string> ()")
./yast2/library/cwm/src/modules/TablePopup.rb:138:        success = Ops.is(value, "map <string, any>")
./nfs-client/src/modules/Nfs.rb:148:      elsif Ops.is(any_settings, "list <map>")
./bootloader/src/include/bootloader/routines/autoinstall.rb:353:          old_format = true if !Ops.is(s, "map <string, any>")
./tune/src/include/hwinfo/routines.rb:982:            if Ops.is(e, "map <string, any>")
Comment 4 Ladislav Slezák 2013-10-17 14:12:43 UTC
I have checked all occurrences listed above and all seems to be ok regarding this bug.

So there seems to be just only one place where it makes problems, so I'll add a workaround just to the yast2-sound package so it does not crash.
Comment 5 Forgotten User 1LnIo8z5Ac 2013-10-17 14:43:36 UTC
Created attachment 563903 [details]
y2logs

cheers
Comment 6 Forgotten User 1LnIo8z5Ac 2013-10-17 14:54:30 UTC
maybe good to know - I switched from rc1 to factory yesterday. The y2log is from today so factory, with the bug still there but with one difference. After the sound-module crashed once, it won´t load another time until you restard the machine. 
Also amarok stopped playing music at the moment I wanted to delete the ati sound-card which is not even used. Alsa or phonon went back from digital output to analog output on the used intel-ICH10 soundchip. That´s why sound stops. Setting back to digital brings sound back without restart.
So this bug in yast-sound seems to be connected to my other bug I filed here:

https://bugzilla.novell.com/show_bug.cgi?id=845923
Comment 7 Ladislav Slezák 2013-10-21 09:24:50 UTC
Fixed in yast2-sound-3.0.3 (you can try the package from OBS home:lslezak - http://download.opensuse.org/repositories/home:/lslezak/openSUSE_13.1/)
Comment 8 Forgotten User 1LnIo8z5Ac 2013-10-21 21:01:09 UTC
confirmed 
I also tested with the 3.1 rpm from factory - this does not work
but 3.0.3 works :)

thanks guys :)