public inbox for gcc-prs@sourceware.org
help / color / mirror / Atom feed
From: peturr02@ru.is
To: gcc-gnats@gcc.gnu.org
Subject: libstdc++/9875: filebuf doesn't handle codecvt::encoding() > 1
Date: Thu, 27 Feb 2003 10:36:00 -0000	[thread overview]
Message-ID: <20030227102718.13478.qmail@sources.redhat.com> (raw)


>Number:         9875
>Category:       libstdc++
>Synopsis:       filebuf doesn't handle codecvt::encoding() > 1
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Feb 27 10:36:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     peturr02@ru.is
>Release:        gcc-3.2.1
>Organization:
>Environment:
Red Hat Linux 8.0
>Description:
Many basic_filebuf members (at least seekoff, seekpos, sync, overflow, underflow) can't handle fixed width multibyte encodings (where codecvt<>::encoding() > 1). It seems that every place _M_file.seekoff is called, it is assumed that codecvt<>::encoding() == 1.
>How-To-Repeat:
See attachment. Note that this test is incomplete because the bug in seekoff shadows some of the other bugs.
>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:
----gnatsweb-attachment----
Content-Type: text/plain; name="seekoffbug.cc"
Content-Disposition: inline; filename="seekoffbug.cc"

#include <fstream>
#include <locale>
#include <algorithm>
#include <cstring>

#undef NDEBUG
#include <cassert>

class Cvt : public std::codecvt<wchar_t, char, mbstate_t>
{
protected:
	virtual std::codecvt_base::result
	do_out(std::mbstate_t&, const wchar_t* from, const wchar_t* from_end,
	       const wchar_t*& from_next, char* to, char* to_end,
	       char*& to_next) const
		{
			std::size_t from_len = from_end - from;
			std::size_t to_len = (to_end - to) / sizeof(wchar_t);
			std::size_t len = std::min(from_len, to_len);
			std::memcpy(to, from, len * sizeof(wchar_t));
			from_next = from + len;
			to_next = to + len * sizeof(wchar_t);
			return from_next == from_end ? std::codecvt_base::ok :
				std::codecvt_base::partial;
		}

	virtual std::codecvt_base::result
	do_in(std::mbstate_t&, const char* from, const char* from_end,
	      const char*& from_next, wchar_t* to, wchar_t* to_end,
	      wchar_t*& to_next) const
		{
			std::size_t from_len =
				(from_end - from) / sizeof(wchar_t);
			std::size_t to_len = to_end - to;
			std::size_t len = std::min(from_len, to_len);
			std::memcpy(to, from, len * sizeof(wchar_t));
			from_next = from + len * sizeof(wchar_t);
			to_next = to + len;
			return from_next == from_end ? std::codecvt_base::ok :
				std::codecvt_base::partial;
		}

	virtual std::codecvt_base::result
	do_unshift(std::mbstate_t&, char*, char*, char*&) const
		{ return std::codecvt_base::noconv; }

	virtual int do_encoding() const throw() { return sizeof(wchar_t); }
	virtual bool do_always_noconv() const throw() { return false; }

	virtual int
	do_length(std::mbstate_t&, const char* from, const char* end,
		  std::size_t max)
		{
			std::size_t len = (end - from) / sizeof(wchar_t);
			return std::min(len, max) * sizeof(wchar_t);
		}

	virtual int do_max_length() const throw() { return sizeof(wchar_t); }
};

void test1()
{
	using namespace std;

	// seekoff
	wfilebuf fb;
	fb.pubimbue(locale(locale::classic(), new Cvt));
	fb.open("tmp", ios_base::out | ios_base::in | ios_base::trunc);
	fb.sputn(L"0123456789", 10);
	fb.pubseekoff(-3, ios_base::cur);
	assert(fb.sgetc() == L'7');
	fb.pubseekoff(-3, ios_base::cur);
	assert(fb.sgetc() == L'4');
	fb.close();
}

void test2()
{
	using namespace std;

	// seekpos
	wfilebuf fb;
	fb.pubimbue(locale(locale::classic(), new Cvt));
	fb.open("tmp", ios_base::out | ios_base::in | ios_base::trunc);
	fb.sputn(L"0123456789", 10);

	streampos p1 = fb.pubseekoff(0, ios_base::cur);
	assert(p1 != streampos(-1));
	fb.sputc(L'a');

	streampos p2 = fb.pubseekpos(p1);
	assert(p2 != streampos(-1));
	assert(p2 == p1);
	assert(fb.sgetc() == L'a');

	fb.pubseekoff(0, ios_base::beg);
	wchar_t buf[11];
	streamsize s1 = fb.sgetn(buf, 11);
	assert(s1 == 11);
	assert(!wmemcmp(buf, L"0123456789a", 11));

	fb.close();
}

void test3()
{
	using namespace std;

	// overflow
	locale loc (locale::classic(), new Cvt);
	wfilebuf fb1;
	fb1.pubimbue(loc);
	fb1.open("tmp", ios_base::out | ios_base::trunc);
	fb1.sputn(L"0123456789", 10);
	fb1.close();

	wfilebuf fb2;
	fb2.pubimbue(loc);
	fb2.open("tmp", ios_base::in | ios_base::out);
	fb2.sputc(L'a');
	fb2.close();

	wfilebuf fb3;
	fb3.pubimbue(loc);
	fb3.open("tmp", ios_base::in);
	assert(fb3.is_open());
	wchar_t buf[10];
	streamsize s1 = fb3.sgetn(buf, 10);
	assert(s1 == 10);
	assert(!wmemcmp(buf, L"a123456789", 10));
	fb3.close();
}

int main()
{
	test1();
	test2();
	test3();

	return 0;
}


             reply	other threads:[~2003-02-27 10:36 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2003-02-27 10:36 peturr02 [this message]
2003-02-28 22:55 paolo
2003-03-01 10:44 paolo
2003-03-03 10:56 Pétur Runólfsson
2003-03-03 11:06 Paolo Carlini
2003-03-03 18:46 Pétur Runólfsson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030227102718.13478.qmail@sources.redhat.com \
    --to=peturr02@ru.is \
    --cc=gcc-gnats@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).