Ticket #2097 (closed merge: fixed)

Opened 5 years ago

Last modified 5 years ago

bug in regEnumKeys (System.Win32.Registry)

Reported by: MagnusTherning Owned by: igloo
Priority: normal Milestone: 6.8.3
Component: libraries (other) Version: 6.8.2
Keywords: Cc:
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description (last modified by igloo) (diff)

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

  Changed 5 years ago 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.

  Changed 5 years ago by igloo

  • difficulty set to Unknown
  • description modified (diff)

  Changed 5 years ago by igloo

  • milestone set to 6.8.3

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

  Changed 5 years ago by igloo

  • owner set to igloo

follow-up: ↓ 6   Changed 5 years ago 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   Changed 5 years ago by MagnusTherning

Replying to igloo:

Fixed: {{{ Sun Apr 6 21:50:51 BST 2008 Ian Lynagh <igloo@…> * 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   Changed 5 years ago by igloo

Replying to MagnusTherning:

Replying to igloo:

Fixed: {{{ Sun Apr 6 21:50:51 BST 2008 Ian Lynagh <igloo@…> * 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   Changed 5 years ago 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.

  Changed 5 years ago 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!

  Changed 5 years ago by simonmar

  • architecture changed from Unknown to Unknown/Multiple
Note: See TracTickets for help on using tickets.