Package: manpages-dev
Version: 3.35-0.1

Hi,

sorry for the loaded title, but that's simply how I'm feeling right now
about this (admittedly not really on the side of manpages-dev) issue.

I'm somewhat semi-appalled about the state (pun intended) of
mbsrtowcs().
- man mbsrtowcs does not mentioning ANYTHING about the heavy
  (and sufficiently non-sequitur, see below)
  initialization requirements of mbstate_t     *)
- http://www.gnu.org/software/libc/manual/html_node/Keeping-the-state.html
  finally does explain it, but it also says
  "There is no specific function or initializer to put the state object
in any specific state."

I would guess that this is because it's the _standard_ which did not
originally define such a function. Which really is a shame
since expecting people to be using a dirt-ugly open-coded memset()
(not domain-specific, easily haywireable length argument, ...) on mbstate_t
in light of even providing a clean mbsinit() to _query_ the state
seems to be fr**** _dirty_ and _asymmetric_ handling
of mbstate_t lifetime.

Besides, one could even postulate that mbsrtowcs() ought to be (have been...)
the one to fully "own" (thus initialize/maintain) the state,
since it's doing a complete, well-formed operation on the string,
from beginning to end.
Thus for me there doesn't appear to be much of a reason for mbsrtowcs()
to (historically) not initialize the foreign variable.
mbstate_t simply is a helper (an opaque memory location) to achieve
proper isolation of program state (per-thread etc.).

BTW, the GNU-specific introduction of mbsnrtowcs() (to work around
problems) indicates that design of the mbs*() API standard
appears to have a history of problems...




*)
on a more modern system (libc-bin 2.13-18),
with uninitialized (random) mbstate_t you get:
  mbsrtowcs: mbsrtowcs_l.c:148: __mbsrtowcs_l: Assertion 
`((data.__statep)->__count == 0)' failed.

On an older (well, medieval) RHEL5,
you get nothing (other than a very buggy app...), except for:
==18039== Conditional jump or move depends on uninitialised value(s)
==18039==    at 0x4EC279A: gconv (in /usr/lib/gconv/EUC-CN.so)
==18039==    by 0x5880BB: __mbsrtowcs_l (in /lib/libc-2.5.so)
==18039==    by 0x57D4C9: mbsrtowcs (in /lib/libc-2.5.so)
...
==18039==  Uninitialised value was created by a stack allocation

iff you've been wise (the pessimist would say: burnt...) enough
to now actually do some Valgrind runs from time to time.



The corresponding test app is:

#include <wchar.h>
#include <string.h> /* memset() */
#include <stdio.h> // stdout

void main () {
  wchar_t arrW[256];

  const char *testA = "Hello World\n";
  const char **ptr_test = &testA;
  mbstate_t mbs;
  //memset(&mbs, 0, sizeof(mbs));

  mbsrtowcs(arrW, ptr_test, sizeof(arrW)/sizeof(*arrW), &mbs);

  fwprintf(stdout, L"%ls", arrW);
}

So, after a long and tiresome tirade, what actually can be done about it?
I'd say the acceptable minimal solution would be to enhance mbsrtowcs()
dox to not fail to mention these crucial init requirements
(but probably there are certain other function dox with the same requirement?).
Perhaps there should be a man page specifically for mbstate_t even!?

So, unless we want "every third" user of mbsrtowcs(3)
to get it wrong, fatally, the documentation should be extended.
A sample phrase would be
"for mbstate_t parameter init, there's no initializer function
defined by the standard - the user is required to have done a proper memset() 
on it."

Thanks,

Andreas Mohr



--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to