1*4882a593SmuzhiyunFrom 0d0dc9e42f27a743171700bcd2ba508ff6e760f9 Mon Sep 17 00:00:00 2001
2*4882a593SmuzhiyunFrom: Florian Weimer <fweimer@redhat.com>
3*4882a593SmuzhiyunDate: Mon, 20 May 2019 21:54:57 +0200
4*4882a593SmuzhiyunSubject: [PATCH 08/20] libio: Remove codecvt vtable [BZ #24588]
5*4882a593Smuzhiyun
6*4882a593SmuzhiyunThe codecvt vtable is not a real vtable because it also contains the
7*4882a593Smuzhiyunconversion state data.  Furthermore, wide stream support was added to
8*4882a593SmuzhiyunGCC 3.0, after a C++ ABI bump, so there is no compatibility
9*4882a593Smuzhiyunrequirement with libstdc++.
10*4882a593Smuzhiyun
11*4882a593SmuzhiyunThis change removes several unmangled function pointers which could
12*4882a593Smuzhiyunbe used with a corrupted FILE object to redirect execution.  (libio
13*4882a593Smuzhiyunvtable verification did not cover the codecvt vtable.)
14*4882a593Smuzhiyun
15*4882a593SmuzhiyunReviewed-by: Yann Droneaud <ydroneaud@opteya.com>
16*4882a593SmuzhiyunReviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
17*4882a593Smuzhiyun(cherry picked from commit 09e1b0e3f6facc1af2dbcfef204f0aaa8718772b)
18*4882a593SmuzhiyunSigned-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
19*4882a593Smuzhiyun---
20*4882a593Smuzhiyun libio/fileops.c     |   3 -
21*4882a593Smuzhiyun libio/iofgetpos.c   |   3 +-
22*4882a593Smuzhiyun libio/iofgetpos64.c |   3 +-
23*4882a593Smuzhiyun libio/iofsetpos.c   |   3 +-
24*4882a593Smuzhiyun libio/iofsetpos64.c |   3 +-
25*4882a593Smuzhiyun libio/iofwide.c     | 132 ++++++--------------------------------------
26*4882a593Smuzhiyun libio/libio.h       |  32 -----------
27*4882a593Smuzhiyun libio/libioP.h      |  29 +++++++++-
28*4882a593Smuzhiyun libio/wfileops.c    |  89 +++++++++++++++--------------
29*4882a593Smuzhiyun 9 files changed, 92 insertions(+), 205 deletions(-)
30*4882a593Smuzhiyun
31*4882a593Smuzhiyundiff --git a/libio/fileops.c b/libio/fileops.c
32*4882a593Smuzhiyunindex c9c5cbcc..dd66cc67 100644
33*4882a593Smuzhiyun--- a/libio/fileops.c
34*4882a593Smuzhiyun+++ b/libio/fileops.c
35*4882a593Smuzhiyun@@ -331,9 +331,6 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun 	  cc = fp->_codecvt = &fp->_wide_data->_codecvt;
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun-	  /* The functions are always the same.  */
40*4882a593Smuzhiyun-	  *cc = __libio_codecvt;
41*4882a593Smuzhiyun-
42*4882a593Smuzhiyun 	  cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
43*4882a593Smuzhiyun 	  cc->__cd_in.__cd.__steps = fcts.towc;
44*4882a593Smuzhiyun
45*4882a593Smuzhiyundiff --git a/libio/iofgetpos.c b/libio/iofgetpos.c
46*4882a593Smuzhiyunindex 8177326c..808ddc47 100644
47*4882a593Smuzhiyun--- a/libio/iofgetpos.c
48*4882a593Smuzhiyun+++ b/libio/iofgetpos.c
49*4882a593Smuzhiyun@@ -70,8 +70,7 @@ _IO_new_fgetpos (FILE *fp, __fpos_t *posp)
50*4882a593Smuzhiyun   else
51*4882a593Smuzhiyun     {
52*4882a593Smuzhiyun       posp->__pos = pos;
53*4882a593Smuzhiyun-      if (fp->_mode > 0
54*4882a593Smuzhiyun-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
55*4882a593Smuzhiyun+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
56*4882a593Smuzhiyun 	/* This is a stateful encoding, safe the state.  */
57*4882a593Smuzhiyun 	posp->__state = fp->_wide_data->_IO_state;
58*4882a593Smuzhiyun     }
59*4882a593Smuzhiyundiff --git a/libio/iofgetpos64.c b/libio/iofgetpos64.c
60*4882a593Smuzhiyunindex 0ec54131..5a0d8bd7 100644
61*4882a593Smuzhiyun--- a/libio/iofgetpos64.c
62*4882a593Smuzhiyun+++ b/libio/iofgetpos64.c
63*4882a593Smuzhiyun@@ -54,8 +54,7 @@ _IO_new_fgetpos64 (FILE *fp, __fpos64_t *posp)
64*4882a593Smuzhiyun   else
65*4882a593Smuzhiyun     {
66*4882a593Smuzhiyun       posp->__pos = pos;
67*4882a593Smuzhiyun-      if (fp->_mode > 0
68*4882a593Smuzhiyun-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
69*4882a593Smuzhiyun+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
70*4882a593Smuzhiyun 	/* This is a stateful encoding, safe the state.  */
71*4882a593Smuzhiyun 	posp->__state = fp->_wide_data->_IO_state;
72*4882a593Smuzhiyun     }
73*4882a593Smuzhiyundiff --git a/libio/iofsetpos.c b/libio/iofsetpos.c
74*4882a593Smuzhiyunindex da48b27c..0cbe3b79 100644
75*4882a593Smuzhiyun--- a/libio/iofsetpos.c
76*4882a593Smuzhiyun+++ b/libio/iofsetpos.c
77*4882a593Smuzhiyun@@ -58,8 +58,7 @@ _IO_new_fsetpos (FILE *fp, const __fpos_t *posp)
78*4882a593Smuzhiyun   else
79*4882a593Smuzhiyun     {
80*4882a593Smuzhiyun       result = 0;
81*4882a593Smuzhiyun-      if (fp->_mode > 0
82*4882a593Smuzhiyun-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
83*4882a593Smuzhiyun+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
84*4882a593Smuzhiyun 	/* This is a stateful encoding, restore the state.  */
85*4882a593Smuzhiyun 	fp->_wide_data->_IO_state = posp->__state;
86*4882a593Smuzhiyun     }
87*4882a593Smuzhiyundiff --git a/libio/iofsetpos64.c b/libio/iofsetpos64.c
88*4882a593Smuzhiyunindex 29da9814..695a8328 100644
89*4882a593Smuzhiyun--- a/libio/iofsetpos64.c
90*4882a593Smuzhiyun+++ b/libio/iofsetpos64.c
91*4882a593Smuzhiyun@@ -48,8 +48,7 @@ _IO_new_fsetpos64 (FILE *fp, const fpos64_t *posp)
92*4882a593Smuzhiyun   else
93*4882a593Smuzhiyun     {
94*4882a593Smuzhiyun       result = 0;
95*4882a593Smuzhiyun-      if (fp->_mode > 0
96*4882a593Smuzhiyun-	  && (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
97*4882a593Smuzhiyun+      if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
98*4882a593Smuzhiyun 	/* This is a stateful encoding, safe the state.  */
99*4882a593Smuzhiyun 	fp->_wide_data->_IO_state = posp->__state;
100*4882a593Smuzhiyun     }
101*4882a593Smuzhiyundiff --git a/libio/iofwide.c b/libio/iofwide.c
102*4882a593Smuzhiyunindex d8ec6642..0e9e7dd5 100644
103*4882a593Smuzhiyun--- a/libio/iofwide.c
104*4882a593Smuzhiyun+++ b/libio/iofwide.c
105*4882a593Smuzhiyun@@ -39,44 +39,6 @@
106*4882a593Smuzhiyun #include <sysdep.h>
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun-/* Prototypes of libio's codecvt functions.  */
110*4882a593Smuzhiyun-static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
111*4882a593Smuzhiyun-				     __mbstate_t *statep,
112*4882a593Smuzhiyun-				     const wchar_t *from_start,
113*4882a593Smuzhiyun-				     const wchar_t *from_end,
114*4882a593Smuzhiyun-				     const wchar_t **from_stop, char *to_start,
115*4882a593Smuzhiyun-				     char *to_end, char **to_stop);
116*4882a593Smuzhiyun-static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt,
117*4882a593Smuzhiyun-					 __mbstate_t *statep, char *to_start,
118*4882a593Smuzhiyun-					 char *to_end, char **to_stop);
119*4882a593Smuzhiyun-static enum __codecvt_result do_in (struct _IO_codecvt *codecvt,
120*4882a593Smuzhiyun-				    __mbstate_t *statep,
121*4882a593Smuzhiyun-				    const char *from_start,
122*4882a593Smuzhiyun-				    const char *from_end,
123*4882a593Smuzhiyun-				    const char **from_stop, wchar_t *to_start,
124*4882a593Smuzhiyun-				    wchar_t *to_end, wchar_t **to_stop);
125*4882a593Smuzhiyun-static int do_encoding (struct _IO_codecvt *codecvt);
126*4882a593Smuzhiyun-static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
127*4882a593Smuzhiyun-		      const char *from_start,
128*4882a593Smuzhiyun-		      const char *from_end, size_t max);
129*4882a593Smuzhiyun-static int do_max_length (struct _IO_codecvt *codecvt);
130*4882a593Smuzhiyun-static int do_always_noconv (struct _IO_codecvt *codecvt);
131*4882a593Smuzhiyun-
132*4882a593Smuzhiyun-
133*4882a593Smuzhiyun-/* The functions used in `codecvt' for libio are always the same.  */
134*4882a593Smuzhiyun-const struct _IO_codecvt __libio_codecvt =
135*4882a593Smuzhiyun-{
136*4882a593Smuzhiyun-  .__codecvt_destr = NULL,		/* Destructor, never used.  */
137*4882a593Smuzhiyun-  .__codecvt_do_out = do_out,
138*4882a593Smuzhiyun-  .__codecvt_do_unshift = do_unshift,
139*4882a593Smuzhiyun-  .__codecvt_do_in = do_in,
140*4882a593Smuzhiyun-  .__codecvt_do_encoding = do_encoding,
141*4882a593Smuzhiyun-  .__codecvt_do_always_noconv = do_always_noconv,
142*4882a593Smuzhiyun-  .__codecvt_do_length = do_length,
143*4882a593Smuzhiyun-  .__codecvt_do_max_length = do_max_length
144*4882a593Smuzhiyun-};
145*4882a593Smuzhiyun-
146*4882a593Smuzhiyun-
147*4882a593Smuzhiyun /* Return orientation of stream.  If mode is nonzero try to change
148*4882a593Smuzhiyun    the orientation first.  */
149*4882a593Smuzhiyun #undef _IO_fwide
150*4882a593Smuzhiyun@@ -119,9 +81,6 @@ _IO_fwide (FILE *fp, int mode)
151*4882a593Smuzhiyun 	assert (fcts.towc_nsteps == 1);
152*4882a593Smuzhiyun 	assert (fcts.tomb_nsteps == 1);
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun-	/* The functions are always the same.  */
155*4882a593Smuzhiyun-	*cc = __libio_codecvt;
156*4882a593Smuzhiyun-
157*4882a593Smuzhiyun 	cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
158*4882a593Smuzhiyun 	cc->__cd_in.__cd.__steps = fcts.towc;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun@@ -151,11 +110,11 @@ _IO_fwide (FILE *fp, int mode)
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun-static enum __codecvt_result
165*4882a593Smuzhiyun-do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
166*4882a593Smuzhiyun-	const wchar_t *from_start, const wchar_t *from_end,
167*4882a593Smuzhiyun-	const wchar_t **from_stop, char *to_start, char *to_end,
168*4882a593Smuzhiyun-	char **to_stop)
169*4882a593Smuzhiyun+enum __codecvt_result
170*4882a593Smuzhiyun+__libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
171*4882a593Smuzhiyun+		     const wchar_t *from_start, const wchar_t *from_end,
172*4882a593Smuzhiyun+		     const wchar_t **from_stop, char *to_start, char *to_end,
173*4882a593Smuzhiyun+		     char **to_stop)
174*4882a593Smuzhiyun {
175*4882a593Smuzhiyun   enum __codecvt_result result;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun@@ -203,57 +162,11 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
178*4882a593Smuzhiyun }
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun
181*4882a593Smuzhiyun-static enum __codecvt_result
182*4882a593Smuzhiyun-do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep,
183*4882a593Smuzhiyun-	    char *to_start, char *to_end, char **to_stop)
184*4882a593Smuzhiyun-{
185*4882a593Smuzhiyun-  enum __codecvt_result result;
186*4882a593Smuzhiyun-
187*4882a593Smuzhiyun-  struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
188*4882a593Smuzhiyun-  int status;
189*4882a593Smuzhiyun-  size_t dummy;
190*4882a593Smuzhiyun-
191*4882a593Smuzhiyun-  codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
192*4882a593Smuzhiyun-  codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
193*4882a593Smuzhiyun-  codecvt->__cd_out.__cd.__data[0].__statep = statep;
194*4882a593Smuzhiyun-
195*4882a593Smuzhiyun-  __gconv_fct fct = gs->__fct;
196*4882a593Smuzhiyun-#ifdef PTR_DEMANGLE
197*4882a593Smuzhiyun-  if (gs->__shlib_handle != NULL)
198*4882a593Smuzhiyun-    PTR_DEMANGLE (fct);
199*4882a593Smuzhiyun-#endif
200*4882a593Smuzhiyun-
201*4882a593Smuzhiyun-  status = DL_CALL_FCT (fct,
202*4882a593Smuzhiyun-			(gs, codecvt->__cd_out.__cd.__data, NULL, NULL,
203*4882a593Smuzhiyun-			 NULL, &dummy, 1, 0));
204*4882a593Smuzhiyun-
205*4882a593Smuzhiyun-  *to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
206*4882a593Smuzhiyun-
207*4882a593Smuzhiyun-  switch (status)
208*4882a593Smuzhiyun-    {
209*4882a593Smuzhiyun-    case __GCONV_OK:
210*4882a593Smuzhiyun-    case __GCONV_EMPTY_INPUT:
211*4882a593Smuzhiyun-      result = __codecvt_ok;
212*4882a593Smuzhiyun-      break;
213*4882a593Smuzhiyun-
214*4882a593Smuzhiyun-    case __GCONV_FULL_OUTPUT:
215*4882a593Smuzhiyun-    case __GCONV_INCOMPLETE_INPUT:
216*4882a593Smuzhiyun-      result = __codecvt_partial;
217*4882a593Smuzhiyun-      break;
218*4882a593Smuzhiyun-
219*4882a593Smuzhiyun-    default:
220*4882a593Smuzhiyun-      result = __codecvt_error;
221*4882a593Smuzhiyun-      break;
222*4882a593Smuzhiyun-    }
223*4882a593Smuzhiyun-
224*4882a593Smuzhiyun-  return result;
225*4882a593Smuzhiyun-}
226*4882a593Smuzhiyun-
227*4882a593Smuzhiyun-
228*4882a593Smuzhiyun-static enum __codecvt_result
229*4882a593Smuzhiyun-do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
230*4882a593Smuzhiyun-       const char *from_start, const char *from_end, const char **from_stop,
231*4882a593Smuzhiyun-       wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
232*4882a593Smuzhiyun+enum __codecvt_result
233*4882a593Smuzhiyun+__libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
234*4882a593Smuzhiyun+		    const char *from_start, const char *from_end,
235*4882a593Smuzhiyun+		    const char **from_stop,
236*4882a593Smuzhiyun+		    wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
237*4882a593Smuzhiyun {
238*4882a593Smuzhiyun   enum __codecvt_result result;
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun@@ -301,8 +214,8 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
241*4882a593Smuzhiyun }
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun-static int
245*4882a593Smuzhiyun-do_encoding (struct _IO_codecvt *codecvt)
246*4882a593Smuzhiyun+int
247*4882a593Smuzhiyun+__libio_codecvt_encoding (struct _IO_codecvt *codecvt)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun   /* See whether the encoding is stateful.  */
250*4882a593Smuzhiyun   if (codecvt->__cd_in.__cd.__steps[0].__stateful)
251*4882a593Smuzhiyun@@ -318,16 +231,10 @@ do_encoding (struct _IO_codecvt *codecvt)
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun-static int
256*4882a593Smuzhiyun-do_always_noconv (struct _IO_codecvt *codecvt)
257*4882a593Smuzhiyun-{
258*4882a593Smuzhiyun-  return 0;
259*4882a593Smuzhiyun-}
260*4882a593Smuzhiyun-
261*4882a593Smuzhiyun-
262*4882a593Smuzhiyun-static int
263*4882a593Smuzhiyun-do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
264*4882a593Smuzhiyun-	   const char *from_start, const char *from_end, size_t max)
265*4882a593Smuzhiyun+int
266*4882a593Smuzhiyun+__libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
267*4882a593Smuzhiyun+			const char *from_start, const char *from_end,
268*4882a593Smuzhiyun+			size_t max)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun   int result;
271*4882a593Smuzhiyun   const unsigned char *cp = (const unsigned char *) from_start;
272*4882a593Smuzhiyun@@ -354,10 +261,3 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun   return result;
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun-
277*4882a593Smuzhiyun-
278*4882a593Smuzhiyun-static int
279*4882a593Smuzhiyun-do_max_length (struct _IO_codecvt *codecvt)
280*4882a593Smuzhiyun-{
281*4882a593Smuzhiyun-  return codecvt->__cd_in.__cd.__steps[0].__max_needed_from;
282*4882a593Smuzhiyun-}
283*4882a593Smuzhiyundiff --git a/libio/libio.h b/libio/libio.h
284*4882a593Smuzhiyunindex 00f91696..5291bb8d 100644
285*4882a593Smuzhiyun--- a/libio/libio.h
286*4882a593Smuzhiyun+++ b/libio/libio.h
287*4882a593Smuzhiyun@@ -118,40 +118,8 @@ struct _IO_marker {
288*4882a593Smuzhiyun   int _pos;
289*4882a593Smuzhiyun };
290*4882a593Smuzhiyun
291*4882a593Smuzhiyun-/* This is the structure from the libstdc++ codecvt class.  */
292*4882a593Smuzhiyun-enum __codecvt_result
293*4882a593Smuzhiyun-{
294*4882a593Smuzhiyun-  __codecvt_ok,
295*4882a593Smuzhiyun-  __codecvt_partial,
296*4882a593Smuzhiyun-  __codecvt_error,
297*4882a593Smuzhiyun-  __codecvt_noconv
298*4882a593Smuzhiyun-};
299*4882a593Smuzhiyun-
300*4882a593Smuzhiyun-/* The order of the elements in the following struct must match the order
301*4882a593Smuzhiyun-   of the virtual functions in the libstdc++ codecvt class.  */
302*4882a593Smuzhiyun struct _IO_codecvt
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun-  void (*__codecvt_destr) (struct _IO_codecvt *);
305*4882a593Smuzhiyun-  enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *,
306*4882a593Smuzhiyun-					     __mbstate_t *,
307*4882a593Smuzhiyun-					     const wchar_t *,
308*4882a593Smuzhiyun-					     const wchar_t *,
309*4882a593Smuzhiyun-					     const wchar_t **, char *,
310*4882a593Smuzhiyun-					     char *, char **);
311*4882a593Smuzhiyun-  enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *,
312*4882a593Smuzhiyun-						 __mbstate_t *, char *,
313*4882a593Smuzhiyun-						 char *, char **);
314*4882a593Smuzhiyun-  enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *,
315*4882a593Smuzhiyun-					    __mbstate_t *,
316*4882a593Smuzhiyun-					    const char *, const char *,
317*4882a593Smuzhiyun-					    const char **, wchar_t *,
318*4882a593Smuzhiyun-					    wchar_t *, wchar_t **);
319*4882a593Smuzhiyun-  int (*__codecvt_do_encoding) (struct _IO_codecvt *);
320*4882a593Smuzhiyun-  int (*__codecvt_do_always_noconv) (struct _IO_codecvt *);
321*4882a593Smuzhiyun-  int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *,
322*4882a593Smuzhiyun-			      const char *, const char *, size_t);
323*4882a593Smuzhiyun-  int (*__codecvt_do_max_length) (struct _IO_codecvt *);
324*4882a593Smuzhiyun-
325*4882a593Smuzhiyun   _IO_iconv_t __cd_in;
326*4882a593Smuzhiyun   _IO_iconv_t __cd_out;
327*4882a593Smuzhiyun };
328*4882a593Smuzhiyundiff --git a/libio/libioP.h b/libio/libioP.h
329*4882a593Smuzhiyunindex df2633d8..7ee71a63 100644
330*4882a593Smuzhiyun--- a/libio/libioP.h
331*4882a593Smuzhiyun+++ b/libio/libioP.h
332*4882a593Smuzhiyun@@ -476,7 +476,6 @@ extern const struct _IO_jump_t _IO_streambuf_jumps;
333*4882a593Smuzhiyun extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden;
334*4882a593Smuzhiyun extern const struct _IO_jump_t _IO_str_jumps attribute_hidden;
335*4882a593Smuzhiyun extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden;
336*4882a593Smuzhiyun-extern const struct _IO_codecvt __libio_codecvt attribute_hidden;
337*4882a593Smuzhiyun extern int _IO_do_write (FILE *, const char *, size_t);
338*4882a593Smuzhiyun libc_hidden_proto (_IO_do_write)
339*4882a593Smuzhiyun extern int _IO_new_do_write (FILE *, const char *, size_t);
340*4882a593Smuzhiyun@@ -839,4 +838,32 @@ IO_validate_vtable (const struct _IO_jump_t *vtable)
341*4882a593Smuzhiyun   return vtable;
342*4882a593Smuzhiyun }
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun+/* Character set conversion.  */
345*4882a593Smuzhiyun+
346*4882a593Smuzhiyun+enum __codecvt_result
347*4882a593Smuzhiyun+{
348*4882a593Smuzhiyun+  __codecvt_ok,
349*4882a593Smuzhiyun+  __codecvt_partial,
350*4882a593Smuzhiyun+  __codecvt_error,
351*4882a593Smuzhiyun+  __codecvt_noconv
352*4882a593Smuzhiyun+};
353*4882a593Smuzhiyun+
354*4882a593Smuzhiyun+enum __codecvt_result __libio_codecvt_out (struct _IO_codecvt *,
355*4882a593Smuzhiyun+					   __mbstate_t *,
356*4882a593Smuzhiyun+					   const wchar_t *,
357*4882a593Smuzhiyun+					   const wchar_t *,
358*4882a593Smuzhiyun+					   const wchar_t **, char *,
359*4882a593Smuzhiyun+					   char *, char **)
360*4882a593Smuzhiyun+  attribute_hidden;
361*4882a593Smuzhiyun+enum __codecvt_result __libio_codecvt_in (struct _IO_codecvt *,
362*4882a593Smuzhiyun+					  __mbstate_t *,
363*4882a593Smuzhiyun+					  const char *, const char *,
364*4882a593Smuzhiyun+					  const char **, wchar_t *,
365*4882a593Smuzhiyun+					  wchar_t *, wchar_t **)
366*4882a593Smuzhiyun+  attribute_hidden;
367*4882a593Smuzhiyun+int __libio_codecvt_encoding (struct _IO_codecvt *) attribute_hidden;
368*4882a593Smuzhiyun+int __libio_codecvt_length (struct _IO_codecvt *, __mbstate_t *,
369*4882a593Smuzhiyun+			    const char *, const char *, size_t)
370*4882a593Smuzhiyun+  attribute_hidden;
371*4882a593Smuzhiyun+
372*4882a593Smuzhiyun #endif /* libioP.h.  */
373*4882a593Smuzhiyundiff --git a/libio/wfileops.c b/libio/wfileops.c
374*4882a593Smuzhiyunindex 63cb6876..ddc96295 100644
375*4882a593Smuzhiyun--- a/libio/wfileops.c
376*4882a593Smuzhiyun+++ b/libio/wfileops.c
377*4882a593Smuzhiyun@@ -72,11 +72,11 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
378*4882a593Smuzhiyun 	    }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun 	  /* Now convert from the internal format into the external buffer.  */
381*4882a593Smuzhiyun-	  result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state,
382*4882a593Smuzhiyun-					    data, data + to_do, &new_data,
383*4882a593Smuzhiyun-					    write_ptr,
384*4882a593Smuzhiyun-					    buf_end,
385*4882a593Smuzhiyun-					    &write_ptr);
386*4882a593Smuzhiyun+	  result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state,
387*4882a593Smuzhiyun+					data, data + to_do, &new_data,
388*4882a593Smuzhiyun+					write_ptr,
389*4882a593Smuzhiyun+					buf_end,
390*4882a593Smuzhiyun+					&write_ptr);
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun 	  /* Write out what we produced so far.  */
393*4882a593Smuzhiyun 	  if (_IO_new_do_write (fp, write_base, write_ptr - write_base) == EOF)
394*4882a593Smuzhiyun@@ -140,12 +140,12 @@ _IO_wfile_underflow (FILE *fp)
395*4882a593Smuzhiyun       fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
396*4882a593Smuzhiyun       fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
397*4882a593Smuzhiyun 	fp->_wide_data->_IO_buf_base;
398*4882a593Smuzhiyun-      status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
399*4882a593Smuzhiyun-				       fp->_IO_read_ptr, fp->_IO_read_end,
400*4882a593Smuzhiyun-				       &read_stop,
401*4882a593Smuzhiyun-				       fp->_wide_data->_IO_read_ptr,
402*4882a593Smuzhiyun-				       fp->_wide_data->_IO_buf_end,
403*4882a593Smuzhiyun-				       &fp->_wide_data->_IO_read_end);
404*4882a593Smuzhiyun+      status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
405*4882a593Smuzhiyun+				   fp->_IO_read_ptr, fp->_IO_read_end,
406*4882a593Smuzhiyun+				   &read_stop,
407*4882a593Smuzhiyun+				   fp->_wide_data->_IO_read_ptr,
408*4882a593Smuzhiyun+				   fp->_wide_data->_IO_buf_end,
409*4882a593Smuzhiyun+				   &fp->_wide_data->_IO_read_end);
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun       fp->_IO_read_base = fp->_IO_read_ptr;
412*4882a593Smuzhiyun       fp->_IO_read_ptr = (char *) read_stop;
413*4882a593Smuzhiyun@@ -266,11 +266,11 @@ _IO_wfile_underflow (FILE *fp)
414*4882a593Smuzhiyun       naccbuf += to_copy;
415*4882a593Smuzhiyun       from = accbuf;
416*4882a593Smuzhiyun     }
417*4882a593Smuzhiyun-  status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
418*4882a593Smuzhiyun-				   from, to, &read_ptr_copy,
419*4882a593Smuzhiyun-				   fp->_wide_data->_IO_read_end,
420*4882a593Smuzhiyun-				   fp->_wide_data->_IO_buf_end,
421*4882a593Smuzhiyun-				   &fp->_wide_data->_IO_read_end);
422*4882a593Smuzhiyun+  status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
423*4882a593Smuzhiyun+			       from, to, &read_ptr_copy,
424*4882a593Smuzhiyun+			       fp->_wide_data->_IO_read_end,
425*4882a593Smuzhiyun+			       fp->_wide_data->_IO_buf_end,
426*4882a593Smuzhiyun+			       &fp->_wide_data->_IO_read_end);
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun   if (__glibc_unlikely (naccbuf != 0))
429*4882a593Smuzhiyun     fp->_IO_read_ptr += MAX (0, read_ptr_copy - &accbuf[naccbuf - to_copy]);
430*4882a593Smuzhiyun@@ -372,12 +372,12 @@ _IO_wfile_underflow_mmap (FILE *fp)
431*4882a593Smuzhiyun   fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
432*4882a593Smuzhiyun   fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
433*4882a593Smuzhiyun     fp->_wide_data->_IO_buf_base;
434*4882a593Smuzhiyun-  (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
435*4882a593Smuzhiyun-			  fp->_IO_read_ptr, fp->_IO_read_end,
436*4882a593Smuzhiyun-			  &read_stop,
437*4882a593Smuzhiyun-			  fp->_wide_data->_IO_read_ptr,
438*4882a593Smuzhiyun-			  fp->_wide_data->_IO_buf_end,
439*4882a593Smuzhiyun-			  &fp->_wide_data->_IO_read_end);
440*4882a593Smuzhiyun+  __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
441*4882a593Smuzhiyun+		      fp->_IO_read_ptr, fp->_IO_read_end,
442*4882a593Smuzhiyun+		      &read_stop,
443*4882a593Smuzhiyun+		      fp->_wide_data->_IO_read_ptr,
444*4882a593Smuzhiyun+		      fp->_wide_data->_IO_buf_end,
445*4882a593Smuzhiyun+		      &fp->_wide_data->_IO_read_end);
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun   fp->_IO_read_ptr = (char *) read_stop;
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun@@ -495,7 +495,7 @@ _IO_wfile_sync (FILE *fp)
450*4882a593Smuzhiyun       struct _IO_codecvt *cv = fp->_codecvt;
451*4882a593Smuzhiyun       off64_t new_pos;
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun-      int clen = (*cv->__codecvt_do_encoding) (cv);
454*4882a593Smuzhiyun+      int clen = __libio_codecvt_encoding (cv);
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun       if (clen > 0)
457*4882a593Smuzhiyun 	/* It is easy, a fixed number of input bytes are used for each
458*4882a593Smuzhiyun@@ -510,9 +510,9 @@ _IO_wfile_sync (FILE *fp)
459*4882a593Smuzhiyun 	  int nread;
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun 	  fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
462*4882a593Smuzhiyun-	  nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
463*4882a593Smuzhiyun-					      fp->_IO_read_base,
464*4882a593Smuzhiyun-					      fp->_IO_read_end, delta);
465*4882a593Smuzhiyun+	  nread = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state,
466*4882a593Smuzhiyun+					  fp->_IO_read_base,
467*4882a593Smuzhiyun+					  fp->_IO_read_end, delta);
468*4882a593Smuzhiyun 	  fp->_IO_read_ptr = fp->_IO_read_base + nread;
469*4882a593Smuzhiyun 	  delta = -(fp->_IO_read_end - fp->_IO_read_base - nread);
470*4882a593Smuzhiyun 	}
471*4882a593Smuzhiyun@@ -547,7 +547,7 @@ adjust_wide_data (FILE *fp, bool do_convert)
472*4882a593Smuzhiyun {
473*4882a593Smuzhiyun   struct _IO_codecvt *cv = fp->_codecvt;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun-  int clen = (*cv->__codecvt_do_encoding) (cv);
476*4882a593Smuzhiyun+  int clen = __libio_codecvt_encoding (cv);
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun   /* Take the easy way out for constant length encodings if we don't need to
479*4882a593Smuzhiyun      convert.  */
480*4882a593Smuzhiyun@@ -564,12 +564,12 @@ adjust_wide_data (FILE *fp, bool do_convert)
481*4882a593Smuzhiyun     {
482*4882a593Smuzhiyun
483*4882a593Smuzhiyun       fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
484*4882a593Smuzhiyun-      status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state,
485*4882a593Smuzhiyun-				       fp->_IO_read_base, fp->_IO_read_ptr,
486*4882a593Smuzhiyun-				       &read_stop,
487*4882a593Smuzhiyun-				       fp->_wide_data->_IO_read_base,
488*4882a593Smuzhiyun-				       fp->_wide_data->_IO_buf_end,
489*4882a593Smuzhiyun-				       &fp->_wide_data->_IO_read_end);
490*4882a593Smuzhiyun+      status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state,
491*4882a593Smuzhiyun+				   fp->_IO_read_base, fp->_IO_read_ptr,
492*4882a593Smuzhiyun+				   &read_stop,
493*4882a593Smuzhiyun+				   fp->_wide_data->_IO_read_base,
494*4882a593Smuzhiyun+				   fp->_wide_data->_IO_buf_end,
495*4882a593Smuzhiyun+				   &fp->_wide_data->_IO_read_end);
496*4882a593Smuzhiyun
497*4882a593Smuzhiyun       /* Should we return EILSEQ?  */
498*4882a593Smuzhiyun       if (__glibc_unlikely (status == __codecvt_error))
499*4882a593Smuzhiyun@@ -647,7 +647,7 @@ do_ftell_wide (FILE *fp)
500*4882a593Smuzhiyun 	}
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun       struct _IO_codecvt *cv = fp->_codecvt;
503*4882a593Smuzhiyun-      int clen = (*cv->__codecvt_do_encoding) (cv);
504*4882a593Smuzhiyun+      int clen = __libio_codecvt_encoding (cv);
505*4882a593Smuzhiyun
506*4882a593Smuzhiyun       if (!unflushed_writes)
507*4882a593Smuzhiyun 	{
508*4882a593Smuzhiyun@@ -662,9 +662,9 @@ do_ftell_wide (FILE *fp)
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun 	      size_t delta = wide_read_ptr - wide_read_base;
511*4882a593Smuzhiyun 	      __mbstate_t state = fp->_wide_data->_IO_last_state;
512*4882a593Smuzhiyun-	      nread = (*cv->__codecvt_do_length) (cv, &state,
513*4882a593Smuzhiyun-						  fp->_IO_read_base,
514*4882a593Smuzhiyun-						  fp->_IO_read_end, delta);
515*4882a593Smuzhiyun+	      nread = __libio_codecvt_length (cv, &state,
516*4882a593Smuzhiyun+					      fp->_IO_read_base,
517*4882a593Smuzhiyun+					      fp->_IO_read_end, delta);
518*4882a593Smuzhiyun 	      offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
519*4882a593Smuzhiyun 	    }
520*4882a593Smuzhiyun 	}
521*4882a593Smuzhiyun@@ -687,9 +687,8 @@ do_ftell_wide (FILE *fp)
522*4882a593Smuzhiyun 	      enum __codecvt_result status;
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun 	      __mbstate_t state = fp->_wide_data->_IO_last_state;
525*4882a593Smuzhiyun-	      status = (*cv->__codecvt_do_out) (cv, &state,
526*4882a593Smuzhiyun-						in, in + delta, &in,
527*4882a593Smuzhiyun-						out, out + outsize, &outstop);
528*4882a593Smuzhiyun+	      status = __libio_codecvt_out (cv, &state, in, in + delta, &in,
529*4882a593Smuzhiyun+					    out, out + outsize, &outstop);
530*4882a593Smuzhiyun
531*4882a593Smuzhiyun 	      /* We don't check for __codecvt_partial because it can be
532*4882a593Smuzhiyun 		 returned on one of two conditions: either the output
533*4882a593Smuzhiyun@@ -800,7 +799,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
534*4882a593Smuzhiyun 	 find out which position in the external buffer corresponds to
535*4882a593Smuzhiyun 	 the current position in the internal buffer.  */
536*4882a593Smuzhiyun       cv = fp->_codecvt;
537*4882a593Smuzhiyun-      clen = (*cv->__codecvt_do_encoding) (cv);
538*4882a593Smuzhiyun+      clen = __libio_codecvt_encoding (cv);
539*4882a593Smuzhiyun
540*4882a593Smuzhiyun       if (mode != 0 || !was_writing)
541*4882a593Smuzhiyun 	{
542*4882a593Smuzhiyun@@ -818,10 +817,10 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
543*4882a593Smuzhiyun 	      delta = (fp->_wide_data->_IO_read_ptr
544*4882a593Smuzhiyun 		       - fp->_wide_data->_IO_read_base);
545*4882a593Smuzhiyun 	      fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
546*4882a593Smuzhiyun-	      nread = (*cv->__codecvt_do_length) (cv,
547*4882a593Smuzhiyun-						  &fp->_wide_data->_IO_state,
548*4882a593Smuzhiyun-						  fp->_IO_read_base,
549*4882a593Smuzhiyun-						  fp->_IO_read_end, delta);
550*4882a593Smuzhiyun+	      nread = __libio_codecvt_length (cv,
551*4882a593Smuzhiyun+					      &fp->_wide_data->_IO_state,
552*4882a593Smuzhiyun+					      fp->_IO_read_base,
553*4882a593Smuzhiyun+					      fp->_IO_read_end, delta);
554*4882a593Smuzhiyun 	      fp->_IO_read_ptr = fp->_IO_read_base + nread;
555*4882a593Smuzhiyun 	      fp->_wide_data->_IO_read_end = fp->_wide_data->_IO_read_ptr;
556*4882a593Smuzhiyun 	      offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
557*4882a593Smuzhiyun--
558*4882a593Smuzhiyun2.20.1
559*4882a593Smuzhiyun
560