Ticket #2097 (closed merge: fixed)

Opened 5 months ago

Last modified 2 months ago

bug in regEnumKeys (System.Win32.Registry)

Reported by: MagnusTherning Assigned to: igloo
Priority: normal Milestone: 6.8.3
Component: libraries (other) Version: 6.8.2
Severity: normal Keywords:
Cc: Difficulty: Unknown
Test Case: Architecture: Unknown
Operating System: Windows

Description (Last modified by igloo)

The following code throws a segmentation fault:

module Main where

import System.Win32.Registry

listRegistry p = do
    putStrLn $ "HKLM\\" ++ p
    hkey <- regOpenKey hKEY_LOCAL_MACHINE p
    sub_paths <- regEnumKeys hkey
    let full_subs = map ((p ++ "\\") ++) sub_paths
    mapM_ listRegistry full_subs
    
main = do
    mapM_ listRegistry ["SOFTWARE\\JavaSoft"]

Change History

02/14/08 13:06:21 changed by MagnusTherning

Hmm, I didn't really intend the code to look like that. I've stuck it in hpaste: http://hpaste.org/5666

Hopefully it'll survive there long enough.

02/15/08 13:26:41 changed by igloo

  • difficulty set to Unknown.
  • description changed.

02/15/08 15:27:23 changed by igloo

  • milestone set to 6.8.3.

I can reproduce this, but it doesn't always segfault for me.

04/06/08 12:51:01 changed by igloo

  • owner set to igloo.

(follow-up: ↓ 6 ) 04/06/08 13:56:46 changed by igloo

  • type changed from bug to merge.

Fixed:

Sun Apr  6 21:50:51 BST 2008  Ian Lynagh <igloo@earth.li>
  * malloc a big enough buffer for the registry functions. Fixes trac #2097.
  We were mallocing a byte per tchar, but tchars are normally 2 bytes big...
  I think they are at most 4 bytes, so we now malloc 4 * #tchars. Not sure
  if there is a proper function I should be using for this?

(in reply to: ↑ 5 ; follow-up: ↓ 7 ) 04/07/08 02:32:53 changed by MagnusTherning

Replying to igloo:

Fixed: {{{ Sun Apr 6 21:50:51 BST 2008 Ian Lynagh <igloo@earth.li> * malloc a big enough buffer for the registry functions. Fixes trac #2097. We were mallocing a byte per tchar, but tchars are normally 2 bytes big... I think they are at most 4 bytes, so we now malloc 4 * #tchars. Not sure if there is a proper function I should be using for this? }}}

One way to be sure is to switch to using wide characters explicitly, i.e. to use RegOpenKeyExW rather than RegOpenKeyEx?.

(in reply to: ↑ 6 ; follow-up: ↓ 8 ) 04/18/08 17:19:43 changed by igloo

Replying to MagnusTherning:

Replying to igloo:

Fixed: {{{ Sun Apr 6 21:50:51 BST 2008 Ian Lynagh <igloo@earth.li> * malloc a big enough buffer for the registry functions. Fixes trac #2097. We were mallocing a byte per tchar, but tchars are normally 2 bytes big... I think they are at most 4 bytes, so we now malloc 4 * #tchars. Not sure if there is a proper function I should be using for this? }}}

One way to be sure is to switch to using wide characters explicitly, i.e. to use RegOpenKeyExW rather than RegOpenKeyEx?.

We are using wide characters explicitly (RegEnumKeyW); the question is how large a buffer to pass as the third argument.

(in reply to: ↑ 7 ) 04/19/08 02:43:10 changed by MagnusTherning

Replying to igloo:

We are using wide characters explicitly (RegEnumKeyW); the question is how large a buffer to pass as the third argument.

All right, maybe I should have been a bit more clear :-) AFAIK the use of TCHAR is something that allows the programmer to switch between Unicode (in Windows parlance) and ASCII at compile time. If the "W functions" are used explicitly I think it'd be better to also use wchar_t explicitly rather than hide them behind TCHARs.

According to Wikipedia "unicode" means UTF-16 on Windows, so allowing up to 4 bytes per character will be enough, though likely a bit wasteful.

04/23/08 05:16:32 changed by igloo

  • status changed from new to closed.
  • resolution set to fixed.

I've merged the patch now, and I'm pretty sure it's safe, if not optimal, so I'm closing the ticket. Patches to improve it are of course welcomed!