GNU bug report logs - #80061
30.2; `cl-loop ... intervals of BUF` can loop forever if BUF isn't the current buffer

Previous Next

Package: emacs;

Reported by: Sasha Podolsky <podolsky.sasha <at> gmail.com>

Date: Tue, 23 Dec 2025 08:43:04 UTC

Severity: normal

Found in version 30.2

To reply to this bug, email your comments to 80061 AT debbugs.gnu.org.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-gnu-emacs <at> gnu.org:
bug#80061; Package emacs. (Tue, 23 Dec 2025 08:43:04 GMT) Full text and rfc822 format available.

Acknowledgement sent to Sasha Podolsky <podolsky.sasha <at> gmail.com>:
New bug report received and forwarded. Copy sent to bug-gnu-emacs <at> gnu.org. (Tue, 23 Dec 2025 08:43:05 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Sasha Podolsky <podolsky.sasha <at> gmail.com>
To: bug-gnu-emacs <at> gnu.org
Subject: 30.2; `cl-loop ... intervals of BUF` can loop forever if BUF isn't
 the current buffer
Date: Tue, 23 Dec 2025 01:44:02 -0500
[Message part 1 (text/plain, inline)]
The following expression triggers an infinite loop:

```
(with-temp-buffer
    (insert #("aaa" 1 2 (test-prop t)))
    (let ((buf (current-buffer))
          (start (point-min))
          (end (point-max)))
      (with-temp-buffer
        (require 'cl-lib)
        ;; (insert "aaa")
        (cl-loop for (istart . iend) being the intervals of buf
                 from start to end
                 do (message "%S" istart)))))
```

The problem is that cl--map-intervals advances its cursor via `(set-marker
mark
next2)`, which creates a mark in the current buffer, not the buffer passed
in
via its `what` arg. This sometimes works out OK. But set-marker apparently
has
some clamping logic, so if the current buffer happens to be too small for
the
position next2, then the cursor doesn't advance and the rest of the
iteration
logic breaks down.

To illustrate that it's a clamping issue: the bug doesn't repro if you
uncomment
the insert into the inner temp buffer.

cl--map-intervals should probably just pass `what` to its set-marker calls.

I think this has been around for a long time, so I think it's just been
unnoticed due to obscurity.

In GNU Emacs 30.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.50,
cairo version 1.18.4)
System Description: Arch Linux

Configured using:
 'configure --with-x-toolkit=gtk3 --sysconfdir=/etc --prefix=/usr
 --libexecdir=/usr/lib --localstatedir=/var --disable-build-details
 --with-cairo --with-harfbuzz --with-libsystemd --with-modules
 --with-native-compilation=aot --with-tree-sitter 'CFLAGS=-march=x86-64
 -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=3
 -Wformat -Werror=format-security -fstack-clash-protection
 -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -g
 -ffile-prefix-map=/build/emacs/src=/usr/src/debug/emacs -flto=auto'
 'LDFLAGS=-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro
 -Wl,-z,now -Wl,-z,pack-relative-relocs -flto=auto''

Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
LCMS2 LIBOTF LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY
INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB

Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: C//

Minor modes in effect:
  global-git-commit-mode: t
  windmove-mode: t
  bug-reference-prog-mode: t
  eglot--managed-mode: t
  flymake-mode: t
  ws-butler-global-mode: t
  ws-butler-mode: t
  corfu-terminal-mode: t
  corfu-history-mode: t
  global-corfu-mode: t
  corfu-mode: t
  popper-echo-mode: t
  popper-mode: t
  global-aggressive-indent-mode: t
  aggressive-indent-mode: t
  backward-forward-mode: t
  mood-line-mode: t
  vertico-buffer-mode: t
  vertico-mode: t
  xclip-mode: t
  whole-line-or-region-global-mode: t
  whole-line-or-region-local-mode: t
  global-treesit-auto-mode: t
  global-kkp-mode: t
  electric-pair-mode: t
  global-subword-mode: t
  subword-mode: t
  global-auto-revert-mode: t
  savehist-mode: t
  which-function-mode: t
  markdown-fenced-yank-tracking-mode: t
  move-to-indent-mode: t
  info-extra-elisp-info-only-mode: t
  send-buffer-cwd-to-term-mode: t
  elpaca-use-package-mode: t
  override-global-mode: t
  my-keys-minor-mode: t
  tooltip-mode: t
  eldoc-mode: t
  show-paren-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  file-name-shadow-mode: t
  context-menu-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  minibuffer-regexp-mode: t
  column-number-mode: t
  line-number-mode: t
  indent-tabs-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/vich/.emacs.d/elpaca/builds/transient/transient hides
/usr/share/emacs/30.2/lisp/transient
~/.emacs.d/lisp/eglot hides /usr/share/emacs/30.2/lisp/progmodes/eglot
~/.emacs.d/lisp/ert hides /usr/share/emacs/30.2/lisp/emacs-lisp/ert

Features:
(shadow sort mail-extr emacsbug expreg orderless magit-extras goto-addr
face-remap magit-bookmark magit-submodule magit-blame magit-stash
magit-reflog magit-bisect magit-push magit-pull magit-fetch magit-clone
magit-remote magit-commit magit-sequence magit-notes magit-worktree
magit-tag magit-merge magit-branch magit-reset magit-files magit-refs
magit-status magit magit-repos magit-apply magit-wip magit-log
magit-diff smerge-mode git-commit log-edit message sendmail puny dired
dired-loaddefs rfc822 mml mml-sec epa epg rfc6068 epg-config gnus-util
mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util
ietf-drums mail-prsvr mailabbrev mail-utils gmm-utils mailheader
pcvs-util magit-core magit-autorevert magit-margin magit-transient
magit-process with-editor shell pcomplete server magit-mode transient
benchmark magit-git magit-base magit-section format-spec crm llama
cond-let sh-script smie executable files-x yank-media markdown-mode
noutline outline pulse color consult-flymake windmove time-date
mood-line-segment-checker vc-git vc-dispatcher bug-reference cc-mode
cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars
cc-defs eglot external-completion jsonrpc consult-xref consult bookmark
xref flymake project diff diff-mode track-changes ert derived pp ewoc
debug backtrace compile comint ansi-osc ansi-color ring c++-ts-mode
c-ts-mode c-ts-common find-func shortdoc text-property-search
vertico-sort cursor-sensor help-fns radix-tree thingatpt
mood-line-segment-vc enriched disp-table facemenu view add-log ws-butler
corfu-terminal popon corfu-history corfu popper-echo popper
aggressive-indent backward-forward mood-line srcery-theme fussy flx
vertico-quick vertico-buffer vertico snap-indent xclip
whole-line-or-region treesit-auto treesit kkp term/xterm xterm compat
benchmark-init advice haskell-mode-autoloads revert-buffer-all-autoloads
znc-autoloads paredit-autoloads rustic-autoloads spinner-autoloads
xterm-color-autoloads rust-mode-autoloads magit-autoloads pcase
magit-section-autoloads llama-autoloads with-editor-autoloads
menuette-autoloads ws-butler-autoloads explain-pause-mode-autoloads
gptel-autoloads transient-autoloads cond-let-autoloads
corfu-terminal-autoloads popon-autoloads corfu-autoloads
popper-autoloads helpful-autoloads elisp-refs-autoloads
eglot-x-autoloads treesit-fold-autoloads aggressive-indent-autoloads
backward-forward-autoloads avy-autoloads mood-line-autoloads
highlight-indent-guides-autoloads srcery-theme-autoloads
consult-eglot-autoloads consult-autoloads fzf-autoloads fussy-autoloads
flx-autoloads orderless-autoloads vertico-autoloads
snap-indent-autoloads ez-query-replace-autoloads xclip-autoloads
expreg-autoloads whole-line-or-region-autoloads
cmake-integration-autoloads f-autoloads s-autoloads tablist-autoloads
ht-autoloads dash-autoloads markdown-mode-autoloads
treesit-auto-autoloads kkp-autoloads benchmark-init-autoloads elec-pair
cap-words superword subword autorevert filenotify savehist edmacro
kmacro elpaca-menu-elpa which-func imenu my-misc comp comp-cstr warnings
comp-run comp-common rx info-extras info term-here elpaca-menu-melpa
elpaca-menu-org elpaca-use-package use-package use-package-ensure
use-package-delight use-package-diminish use-package-bind-key bind-key
elpaca-use-package-autoloads package browse-url url url-proxy
url-privacy url-expand url-methods url-history url-cookie
generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse
auth-source eieio eieio-core icons password-cache json subr-x map
byte-opt url-vars elpaca elpaca-process elpaca-autoloads easy-mmode
cl-macs gv cl-extra help-mode cl-seq use-package-core cl-loaddefs cl-lib
bytecomp byte-compile rmc iso-transl tooltip cconv eldoc paren electric
uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
term/x-win x-win term/common-win x-dnd touch-screen tool-bar dnd fontset
image regexp-opt fringe tabulated-list replace newcomment text-mode
lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch
easymenu timer select scroll-bar mouse jit-lock font-lock syntax
font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
romanian slovak czech european ethiopic indian cyrillic chinese
composite emoji-zwj charscript charprop case-table epa-hook
jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
theme-loaddefs faces cus-face macroexp files window text-properties
overlay sha1 md5 base64 format env code-pages mule custom widget keymap
hashtable-print-readable backquote threads dbusbind inotify lcms2
dynamic-setting system-font-setting font-render-setting cairo gtk
x-toolkit xinput2 x multi-tty move-toolbar make-network-process
native-compile emacs)

Memory information:
((conses 16 1489093 1453595) (symbols 48 33166 372) (strings 32 275344
59425)
 (string-bytes 1 5549517) (vectors 16 88647) (vector-slots 8 1232473
509070) (floats 8 648 1826)
 (intervals 56 120189 55226) (buffers 992 30))
[Message part 2 (text/html, inline)]

Information forwarded to bug-gnu-emacs <at> gnu.org:
bug#80061; Package emacs. (Wed, 24 Dec 2025 15:59:01 GMT) Full text and rfc822 format available.

Message #8 received at 80061 <at> debbugs.gnu.org (full text, mbox):

From: Philip Kaludercic <philipk <at> posteo.net>
To: Sasha Podolsky <podolsky.sasha <at> gmail.com>
Cc: 80061 <at> debbugs.gnu.org
Subject: Re: bug#80061: 30.2; `cl-loop ... intervals of BUF` can loop
 forever if BUF isn't the current buffer
Date: Wed, 24 Dec 2025 15:58:23 +0000
[Message part 1 (text/plain, inline)]
Sasha Podolsky <podolsky.sasha <at> gmail.com> writes:

> The following expression triggers an infinite loop:
>
> ```
> (with-temp-buffer
>     (insert #("aaa" 1 2 (test-prop t)))
>     (let ((buf (current-buffer))
>           (start (point-min))
>           (end (point-max)))
>       (with-temp-buffer
>         (require 'cl-lib)
>         ;; (insert "aaa")
>         (cl-loop for (istart . iend) being the intervals of buf
>                  from start to end
>                  do (message "%S" istart)))))
> ```
>
> The problem is that cl--map-intervals advances its cursor via `(set-marker
> mark
> next2)`, which creates a mark in the current buffer, not the buffer passed
> in
> via its `what` arg. This sometimes works out OK. But set-marker apparently
> has
> some clamping logic, so if the current buffer happens to be too small for
> the
> position next2, then the cursor doesn't advance and the rest of the
> iteration
> logic breaks down.
>
> To illustrate that it's a clamping issue: the bug doesn't repro if you
> uncomment
> the insert into the inner temp buffer.
>
> cl--map-intervals should probably just pass `what` to its set-marker calls.

So to be concrete:

[Message part 2 (text/x-patch, inline)]
diff --git a/lisp/emacs-lisp/cl-extra.el b/lisp/emacs-lisp/cl-extra.el
index 0c80400d028..24ae6c6575e 100644
--- a/lisp/emacs-lisp/cl-extra.el
+++ b/lisp/emacs-lisp/cl-extra.el
@@ -281,9 +281,9 @@ cl--map-intervals
                 next2 (or next (with-current-buffer what
                                  (point-max))))
           (funcall func (prog1 (marker-position mark)
-                          (set-marker mark next2))
+                          (set-marker mark next2 what))
                    (if mark2 (min next2 mark2) next2)))
-        (set-marker mark nil) (if mark2 (set-marker mark2 nil)))
+        (set-marker mark nil what) (if mark2 (set-marker mark2 nil what)))
     (or start (setq start 0))
     (or end (setq end (length what)))
     (while (< start end)
[Message part 3 (text/plain, inline)]
I think it would also be helpful to add a test to "cl-macs-tests.el".

> I think this has been around for a long time, so I think it's just been
> unnoticed due to obscurity.
>
> In GNU Emacs 30.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.50,
> cairo version 1.18.4)
> System Description: Arch Linux
>
> Configured using:
>  'configure --with-x-toolkit=gtk3 --sysconfdir=/etc --prefix=/usr
>  --libexecdir=/usr/lib --localstatedir=/var --disable-build-details
>  --with-cairo --with-harfbuzz --with-libsystemd --with-modules
>  --with-native-compilation=aot --with-tree-sitter 'CFLAGS=-march=x86-64
>  -mtune=generic -O2 -pipe -fno-plt -fexceptions -Wp,-D_FORTIFY_SOURCE=3
>  -Wformat -Werror=format-security -fstack-clash-protection
>  -fcf-protection -fno-omit-frame-pointer -mno-omit-leaf-frame-pointer -g
>  -ffile-prefix-map=/build/emacs/src=/usr/src/debug/emacs -flto=auto'
>  'LDFLAGS=-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro
>  -Wl,-z,now -Wl,-z,pack-relative-relocs -flto=auto''
>
> Configured features:
> ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
> LCMS2 LIBOTF LIBSYSTEMD LIBXML2 M17N_FLT MODULES NATIVE_COMP NOTIFY
> INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3 THREADS TIFF
> TOOLKIT_SCROLL_BARS TREE_SITTER WEBP X11 XDBE XIM XINPUT2 XPM GTK3 ZLIB
>
> Important settings:
>   value of $LANG: en_US.UTF-8
>   locale-coding-system: utf-8-unix
>
> Major mode: C//
>
> Minor modes in effect:
>   global-git-commit-mode: t
>   windmove-mode: t
>   bug-reference-prog-mode: t
>   eglot--managed-mode: t
>   flymake-mode: t
>   ws-butler-global-mode: t
>   ws-butler-mode: t
>   corfu-terminal-mode: t
>   corfu-history-mode: t
>   global-corfu-mode: t
>   corfu-mode: t
>   popper-echo-mode: t
>   popper-mode: t
>   global-aggressive-indent-mode: t
>   aggressive-indent-mode: t
>   backward-forward-mode: t
>   mood-line-mode: t
>   vertico-buffer-mode: t
>   vertico-mode: t
>   xclip-mode: t
>   whole-line-or-region-global-mode: t
>   whole-line-or-region-local-mode: t
>   global-treesit-auto-mode: t
>   global-kkp-mode: t
>   electric-pair-mode: t
>   global-subword-mode: t
>   subword-mode: t
>   global-auto-revert-mode: t
>   savehist-mode: t
>   which-function-mode: t
>   markdown-fenced-yank-tracking-mode: t
>   move-to-indent-mode: t
>   info-extra-elisp-info-only-mode: t
>   send-buffer-cwd-to-term-mode: t
>   elpaca-use-package-mode: t
>   override-global-mode: t
>   my-keys-minor-mode: t
>   tooltip-mode: t
>   eldoc-mode: t
>   show-paren-mode: t
>   electric-indent-mode: t
>   mouse-wheel-mode: t
>   tool-bar-mode: t
>   file-name-shadow-mode: t
>   context-menu-mode: t
>   global-font-lock-mode: t
>   font-lock-mode: t
>   blink-cursor-mode: t
>   minibuffer-regexp-mode: t
>   column-number-mode: t
>   line-number-mode: t
>   indent-tabs-mode: t
>   transient-mark-mode: t
>   auto-composition-mode: t
>   auto-encryption-mode: t
>   auto-compression-mode: t
>
> Load-path shadows:
> /home/vich/.emacs.d/elpaca/builds/transient/transient hides
> /usr/share/emacs/30.2/lisp/transient
> ~/.emacs.d/lisp/eglot hides /usr/share/emacs/30.2/lisp/progmodes/eglot
> ~/.emacs.d/lisp/ert hides /usr/share/emacs/30.2/lisp/emacs-lisp/ert
>
> Features:
> (shadow sort mail-extr emacsbug expreg orderless magit-extras goto-addr
> face-remap magit-bookmark magit-submodule magit-blame magit-stash
> magit-reflog magit-bisect magit-push magit-pull magit-fetch magit-clone
> magit-remote magit-commit magit-sequence magit-notes magit-worktree
> magit-tag magit-merge magit-branch magit-reset magit-files magit-refs
> magit-status magit magit-repos magit-apply magit-wip magit-log
> magit-diff smerge-mode git-commit log-edit message sendmail puny dired
> dired-loaddefs rfc822 mml mml-sec epa epg rfc6068 epg-config gnus-util
> mm-decode mm-bodies mm-encode mail-parse rfc2231 rfc2047 rfc2045 mm-util
> ietf-drums mail-prsvr mailabbrev mail-utils gmm-utils mailheader
> pcvs-util magit-core magit-autorevert magit-margin magit-transient
> magit-process with-editor shell pcomplete server magit-mode transient
> benchmark magit-git magit-base magit-section format-spec crm llama
> cond-let sh-script smie executable files-x yank-media markdown-mode
> noutline outline pulse color consult-flymake windmove time-date
> mood-line-segment-checker vc-git vc-dispatcher bug-reference cc-mode
> cc-fonts cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars
> cc-defs eglot external-completion jsonrpc consult-xref consult bookmark
> xref flymake project diff diff-mode track-changes ert derived pp ewoc
> debug backtrace compile comint ansi-osc ansi-color ring c++-ts-mode
> c-ts-mode c-ts-common find-func shortdoc text-property-search
> vertico-sort cursor-sensor help-fns radix-tree thingatpt
> mood-line-segment-vc enriched disp-table facemenu view add-log ws-butler
> corfu-terminal popon corfu-history corfu popper-echo popper
> aggressive-indent backward-forward mood-line srcery-theme fussy flx
> vertico-quick vertico-buffer vertico snap-indent xclip
> whole-line-or-region treesit-auto treesit kkp term/xterm xterm compat
> benchmark-init advice haskell-mode-autoloads revert-buffer-all-autoloads
> znc-autoloads paredit-autoloads rustic-autoloads spinner-autoloads
> xterm-color-autoloads rust-mode-autoloads magit-autoloads pcase
> magit-section-autoloads llama-autoloads with-editor-autoloads
> menuette-autoloads ws-butler-autoloads explain-pause-mode-autoloads
> gptel-autoloads transient-autoloads cond-let-autoloads
> corfu-terminal-autoloads popon-autoloads corfu-autoloads
> popper-autoloads helpful-autoloads elisp-refs-autoloads
> eglot-x-autoloads treesit-fold-autoloads aggressive-indent-autoloads
> backward-forward-autoloads avy-autoloads mood-line-autoloads
> highlight-indent-guides-autoloads srcery-theme-autoloads
> consult-eglot-autoloads consult-autoloads fzf-autoloads fussy-autoloads
> flx-autoloads orderless-autoloads vertico-autoloads
> snap-indent-autoloads ez-query-replace-autoloads xclip-autoloads
> expreg-autoloads whole-line-or-region-autoloads
> cmake-integration-autoloads f-autoloads s-autoloads tablist-autoloads
> ht-autoloads dash-autoloads markdown-mode-autoloads
> treesit-auto-autoloads kkp-autoloads benchmark-init-autoloads elec-pair
> cap-words superword subword autorevert filenotify savehist edmacro
> kmacro elpaca-menu-elpa which-func imenu my-misc comp comp-cstr warnings
> comp-run comp-common rx info-extras info term-here elpaca-menu-melpa
> elpaca-menu-org elpaca-use-package use-package use-package-ensure
> use-package-delight use-package-diminish use-package-bind-key bind-key
> elpaca-use-package-autoloads package browse-url url url-proxy
> url-privacy url-expand url-methods url-history url-cookie
> generate-lisp-file url-domsuf url-util mailcap url-handlers url-parse
> auth-source eieio eieio-core icons password-cache json subr-x map
> byte-opt url-vars elpaca elpaca-process elpaca-autoloads easy-mmode
> cl-macs gv cl-extra help-mode cl-seq use-package-core cl-loaddefs cl-lib
> bytecomp byte-compile rmc iso-transl tooltip cconv eldoc paren electric
> uniquify ediff-hook vc-hooks lisp-float-type elisp-mode mwheel
> term/x-win x-win term/common-win x-dnd touch-screen tool-bar dnd fontset
> image regexp-opt fringe tabulated-list replace newcomment text-mode
> lisp-mode prog-mode register page tab-bar menu-bar rfn-eshadow isearch
> easymenu timer select scroll-bar mouse jit-lock font-lock syntax
> font-core term/tty-colors frame minibuffer nadvice seq simple cl-generic
> indonesian philippine cham georgian utf-8-lang misc-lang vietnamese
> tibetan thai tai-viet lao korean japanese eucjp-ms cp51932 hebrew greek
> romanian slovak czech european ethiopic indian cyrillic chinese
> composite emoji-zwj charscript charprop case-table epa-hook
> jka-cmpr-hook help abbrev obarray oclosure cl-preloaded button loaddefs
> theme-loaddefs faces cus-face macroexp files window text-properties
> overlay sha1 md5 base64 format env code-pages mule custom widget keymap
> hashtable-print-readable backquote threads dbusbind inotify lcms2
> dynamic-setting system-font-setting font-render-setting cairo gtk
> x-toolkit xinput2 x multi-tty move-toolbar make-network-process
> native-compile emacs)
>
> Memory information:
> ((conses 16 1489093 1453595) (symbols 48 33166 372) (strings 32 275344
> 59425)
>  (string-bytes 1 5549517) (vectors 16 88647) (vector-slots 8 1232473
> 509070) (floats 8 648 1826)
>  (intervals 56 120189 55226) (buffers 992 30))

This bug report was last modified today.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.