mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
libio: Remove codecvt vtable [BZ #24588]
The codecvt vtable is not a real vtable because it also contains the conversion state data. Furthermore, wide stream support was added to GCC 3.0, after a C++ ABI bump, so there is no compatibility requirement with libstdc++. This change removes several unmangled function pointers which could be used with a corrupted FILE object to redirect execution. (libio vtable verification did not cover the codecvt vtable.) Reviewed-by: Yann Droneaud <ydroneaud@opteya.com> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
43
ChangeLog
43
ChangeLog
@ -1,3 +1,46 @@
|
|||||||
|
2019-05-20 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
[BZ #24588]
|
||||||
|
libio: Remove codecvt vtable.
|
||||||
|
* libio/fileops.c ( _IO_new_file_fopen): Do not copy
|
||||||
|
__libio_codecvt.
|
||||||
|
* libio/iofgetpos.c (_IO_new_fgetpos): Call
|
||||||
|
__libio_codecvt_encoding.
|
||||||
|
* libio/iofgetpos64.c (_IO_new_fgetpos): Likewise.
|
||||||
|
* libio/iofsetpos.c (_IO_new_fsetpos): Likewise.
|
||||||
|
* libio/iofsetpos64.c (_IO_new_fsetpos): Likewise.
|
||||||
|
* libio/iofwide.c (__libio_codecvt): Remove variable.
|
||||||
|
(_IO_fwide): Do not copy __libio_codecvt.
|
||||||
|
(__libio_codecvt_out): Rename from do_out and export.
|
||||||
|
(do_unshift): Remove function.
|
||||||
|
(__libio_codecvt_in): Rename from do_in and export.
|
||||||
|
(__libio_codecvt_encoding): Rename from do_encoding and export.
|
||||||
|
(do_always_noconv): Remove function.
|
||||||
|
(__libio_codecvt_length): Rename from do_length and export.
|
||||||
|
(do_max_length): Remove function.
|
||||||
|
* libio/libio.h (enum __codecvt_result): Remove definition; moved
|
||||||
|
to libioP.h.
|
||||||
|
(struct _IO_codecvt): Remove fields __codecvt_destr,
|
||||||
|
__codecvt_do_out, __codecvt_do_unshift, __codecvt_do_in,
|
||||||
|
__codecvt_do_encoding, __codecvt_do_always_noconv,
|
||||||
|
__codecvt_do_length, __codecvt_do_max_length.
|
||||||
|
* libio/libioP.h (enum __codecvt_result): Define; moved from
|
||||||
|
libio.h.
|
||||||
|
(__libio_codecvt_out, __libio_codecvt_in)
|
||||||
|
(__libio_codecvt_encoding, __libio_codecvt_length): Declare
|
||||||
|
functions.
|
||||||
|
* libio/wfileops.c (_IO_wdo_write): Call __libio_codecvt_out.
|
||||||
|
(_IO_wfile_underflow): Call __libio_codecvt_in.
|
||||||
|
(_IO_wfile_underflow): Likewise.
|
||||||
|
(_IO_wfile_underflow_mmap): Likewise.
|
||||||
|
(_IO_wfile_sync): Call __libio_codecvt_encoding,
|
||||||
|
__libio_codecvt_length.
|
||||||
|
(adjust_wide_data): Call __libio_codecvt_encoding,
|
||||||
|
__libio_codecvt_in.
|
||||||
|
(do_ftell_wide): Call __libio_codecvt_length, __libio_codecvt_out.
|
||||||
|
(_IO_wfile_seekoff): Call __libio_codecvt_encoding,
|
||||||
|
__libio_codecvt_length.
|
||||||
|
|
||||||
2019-05-20 Florian Weimer <fweimer@redhat.com>
|
2019-05-20 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
* support/support.h (support_sbindir_prefix): Declare.
|
* support/support.h (support_sbindir_prefix): Declare.
|
||||||
|
@ -331,9 +331,6 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,
|
|||||||
|
|
||||||
cc = fp->_codecvt = &fp->_wide_data->_codecvt;
|
cc = fp->_codecvt = &fp->_wide_data->_codecvt;
|
||||||
|
|
||||||
/* The functions are always the same. */
|
|
||||||
*cc = __libio_codecvt;
|
|
||||||
|
|
||||||
cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
|
cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
|
||||||
cc->__cd_in.__cd.__steps = fcts.towc;
|
cc->__cd_in.__cd.__steps = fcts.towc;
|
||||||
|
|
||||||
|
@ -70,8 +70,7 @@ _IO_new_fgetpos (FILE *fp, __fpos_t *posp)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
posp->__pos = pos;
|
posp->__pos = pos;
|
||||||
if (fp->_mode > 0
|
if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
|
||||||
&& (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
|
|
||||||
/* This is a stateful encoding, safe the state. */
|
/* This is a stateful encoding, safe the state. */
|
||||||
posp->__state = fp->_wide_data->_IO_state;
|
posp->__state = fp->_wide_data->_IO_state;
|
||||||
}
|
}
|
||||||
|
@ -54,8 +54,7 @@ _IO_new_fgetpos64 (FILE *fp, __fpos64_t *posp)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
posp->__pos = pos;
|
posp->__pos = pos;
|
||||||
if (fp->_mode > 0
|
if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
|
||||||
&& (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
|
|
||||||
/* This is a stateful encoding, safe the state. */
|
/* This is a stateful encoding, safe the state. */
|
||||||
posp->__state = fp->_wide_data->_IO_state;
|
posp->__state = fp->_wide_data->_IO_state;
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,7 @@ _IO_new_fsetpos (FILE *fp, const __fpos_t *posp)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = 0;
|
result = 0;
|
||||||
if (fp->_mode > 0
|
if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
|
||||||
&& (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
|
|
||||||
/* This is a stateful encoding, restore the state. */
|
/* This is a stateful encoding, restore the state. */
|
||||||
fp->_wide_data->_IO_state = posp->__state;
|
fp->_wide_data->_IO_state = posp->__state;
|
||||||
}
|
}
|
||||||
|
@ -48,8 +48,7 @@ _IO_new_fsetpos64 (FILE *fp, const fpos64_t *posp)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
result = 0;
|
result = 0;
|
||||||
if (fp->_mode > 0
|
if (fp->_mode > 0 && __libio_codecvt_encoding (fp->_codecvt) < 0)
|
||||||
&& (*fp->_codecvt->__codecvt_do_encoding) (fp->_codecvt) < 0)
|
|
||||||
/* This is a stateful encoding, safe the state. */
|
/* This is a stateful encoding, safe the state. */
|
||||||
fp->_wide_data->_IO_state = posp->__state;
|
fp->_wide_data->_IO_state = posp->__state;
|
||||||
}
|
}
|
||||||
|
124
libio/iofwide.c
124
libio/iofwide.c
@ -39,44 +39,6 @@
|
|||||||
#include <sysdep.h>
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
|
||||||
/* Prototypes of libio's codecvt functions. */
|
|
||||||
static enum __codecvt_result do_out (struct _IO_codecvt *codecvt,
|
|
||||||
__mbstate_t *statep,
|
|
||||||
const wchar_t *from_start,
|
|
||||||
const wchar_t *from_end,
|
|
||||||
const wchar_t **from_stop, char *to_start,
|
|
||||||
char *to_end, char **to_stop);
|
|
||||||
static enum __codecvt_result do_unshift (struct _IO_codecvt *codecvt,
|
|
||||||
__mbstate_t *statep, char *to_start,
|
|
||||||
char *to_end, char **to_stop);
|
|
||||||
static enum __codecvt_result do_in (struct _IO_codecvt *codecvt,
|
|
||||||
__mbstate_t *statep,
|
|
||||||
const char *from_start,
|
|
||||||
const char *from_end,
|
|
||||||
const char **from_stop, wchar_t *to_start,
|
|
||||||
wchar_t *to_end, wchar_t **to_stop);
|
|
||||||
static int do_encoding (struct _IO_codecvt *codecvt);
|
|
||||||
static int do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
|
||||||
const char *from_start,
|
|
||||||
const char *from_end, size_t max);
|
|
||||||
static int do_max_length (struct _IO_codecvt *codecvt);
|
|
||||||
static int do_always_noconv (struct _IO_codecvt *codecvt);
|
|
||||||
|
|
||||||
|
|
||||||
/* The functions used in `codecvt' for libio are always the same. */
|
|
||||||
const struct _IO_codecvt __libio_codecvt =
|
|
||||||
{
|
|
||||||
.__codecvt_destr = NULL, /* Destructor, never used. */
|
|
||||||
.__codecvt_do_out = do_out,
|
|
||||||
.__codecvt_do_unshift = do_unshift,
|
|
||||||
.__codecvt_do_in = do_in,
|
|
||||||
.__codecvt_do_encoding = do_encoding,
|
|
||||||
.__codecvt_do_always_noconv = do_always_noconv,
|
|
||||||
.__codecvt_do_length = do_length,
|
|
||||||
.__codecvt_do_max_length = do_max_length
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* Return orientation of stream. If mode is nonzero try to change
|
/* Return orientation of stream. If mode is nonzero try to change
|
||||||
the orientation first. */
|
the orientation first. */
|
||||||
#undef _IO_fwide
|
#undef _IO_fwide
|
||||||
@ -118,9 +80,6 @@ _IO_fwide (FILE *fp, int mode)
|
|||||||
assert (fcts.towc_nsteps == 1);
|
assert (fcts.towc_nsteps == 1);
|
||||||
assert (fcts.tomb_nsteps == 1);
|
assert (fcts.tomb_nsteps == 1);
|
||||||
|
|
||||||
/* The functions are always the same. */
|
|
||||||
*cc = __libio_codecvt;
|
|
||||||
|
|
||||||
cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
|
cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
|
||||||
cc->__cd_in.__cd.__steps = fcts.towc;
|
cc->__cd_in.__cd.__steps = fcts.towc;
|
||||||
|
|
||||||
@ -150,8 +109,8 @@ _IO_fwide (FILE *fp, int mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static enum __codecvt_result
|
enum __codecvt_result
|
||||||
do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
__libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
||||||
const wchar_t *from_start, const wchar_t *from_end,
|
const wchar_t *from_start, const wchar_t *from_end,
|
||||||
const wchar_t **from_stop, char *to_start, char *to_end,
|
const wchar_t **from_stop, char *to_start, char *to_end,
|
||||||
char **to_stop)
|
char **to_stop)
|
||||||
@ -202,56 +161,10 @@ do_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static enum __codecvt_result
|
enum __codecvt_result
|
||||||
do_unshift (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
__libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
||||||
char *to_start, char *to_end, char **to_stop)
|
const char *from_start, const char *from_end,
|
||||||
{
|
const char **from_stop,
|
||||||
enum __codecvt_result result;
|
|
||||||
|
|
||||||
struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
|
|
||||||
int status;
|
|
||||||
size_t dummy;
|
|
||||||
|
|
||||||
codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
|
|
||||||
codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
|
|
||||||
codecvt->__cd_out.__cd.__data[0].__statep = statep;
|
|
||||||
|
|
||||||
__gconv_fct fct = gs->__fct;
|
|
||||||
#ifdef PTR_DEMANGLE
|
|
||||||
if (gs->__shlib_handle != NULL)
|
|
||||||
PTR_DEMANGLE (fct);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
status = DL_CALL_FCT (fct,
|
|
||||||
(gs, codecvt->__cd_out.__cd.__data, NULL, NULL,
|
|
||||||
NULL, &dummy, 1, 0));
|
|
||||||
|
|
||||||
*to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
|
|
||||||
|
|
||||||
switch (status)
|
|
||||||
{
|
|
||||||
case __GCONV_OK:
|
|
||||||
case __GCONV_EMPTY_INPUT:
|
|
||||||
result = __codecvt_ok;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case __GCONV_FULL_OUTPUT:
|
|
||||||
case __GCONV_INCOMPLETE_INPUT:
|
|
||||||
result = __codecvt_partial;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
result = __codecvt_error;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static enum __codecvt_result
|
|
||||||
do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
|
||||||
const char *from_start, const char *from_end, const char **from_stop,
|
|
||||||
wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
|
wchar_t *to_start, wchar_t *to_end, wchar_t **to_stop)
|
||||||
{
|
{
|
||||||
enum __codecvt_result result;
|
enum __codecvt_result result;
|
||||||
@ -300,8 +213,8 @@ do_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
int
|
||||||
do_encoding (struct _IO_codecvt *codecvt)
|
__libio_codecvt_encoding (struct _IO_codecvt *codecvt)
|
||||||
{
|
{
|
||||||
/* See whether the encoding is stateful. */
|
/* See whether the encoding is stateful. */
|
||||||
if (codecvt->__cd_in.__cd.__steps[0].__stateful)
|
if (codecvt->__cd_in.__cd.__steps[0].__stateful)
|
||||||
@ -317,16 +230,10 @@ do_encoding (struct _IO_codecvt *codecvt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
int
|
||||||
do_always_noconv (struct _IO_codecvt *codecvt)
|
__libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
||||||
{
|
const char *from_start, const char *from_end,
|
||||||
return 0;
|
size_t max)
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
|
||||||
const char *from_start, const char *from_end, size_t max)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
const unsigned char *cp = (const unsigned char *) from_start;
|
const unsigned char *cp = (const unsigned char *) from_start;
|
||||||
@ -353,10 +260,3 @@ do_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
|
||||||
do_max_length (struct _IO_codecvt *codecvt)
|
|
||||||
{
|
|
||||||
return codecvt->__cd_in.__cd.__steps[0].__max_needed_from;
|
|
||||||
}
|
|
||||||
|
@ -116,40 +116,8 @@ struct _IO_marker {
|
|||||||
int _pos;
|
int _pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This is the structure from the libstdc++ codecvt class. */
|
|
||||||
enum __codecvt_result
|
|
||||||
{
|
|
||||||
__codecvt_ok,
|
|
||||||
__codecvt_partial,
|
|
||||||
__codecvt_error,
|
|
||||||
__codecvt_noconv
|
|
||||||
};
|
|
||||||
|
|
||||||
/* The order of the elements in the following struct must match the order
|
|
||||||
of the virtual functions in the libstdc++ codecvt class. */
|
|
||||||
struct _IO_codecvt
|
struct _IO_codecvt
|
||||||
{
|
{
|
||||||
void (*__codecvt_destr) (struct _IO_codecvt *);
|
|
||||||
enum __codecvt_result (*__codecvt_do_out) (struct _IO_codecvt *,
|
|
||||||
__mbstate_t *,
|
|
||||||
const wchar_t *,
|
|
||||||
const wchar_t *,
|
|
||||||
const wchar_t **, char *,
|
|
||||||
char *, char **);
|
|
||||||
enum __codecvt_result (*__codecvt_do_unshift) (struct _IO_codecvt *,
|
|
||||||
__mbstate_t *, char *,
|
|
||||||
char *, char **);
|
|
||||||
enum __codecvt_result (*__codecvt_do_in) (struct _IO_codecvt *,
|
|
||||||
__mbstate_t *,
|
|
||||||
const char *, const char *,
|
|
||||||
const char **, wchar_t *,
|
|
||||||
wchar_t *, wchar_t **);
|
|
||||||
int (*__codecvt_do_encoding) (struct _IO_codecvt *);
|
|
||||||
int (*__codecvt_do_always_noconv) (struct _IO_codecvt *);
|
|
||||||
int (*__codecvt_do_length) (struct _IO_codecvt *, __mbstate_t *,
|
|
||||||
const char *, const char *, size_t);
|
|
||||||
int (*__codecvt_do_max_length) (struct _IO_codecvt *);
|
|
||||||
|
|
||||||
_IO_iconv_t __cd_in;
|
_IO_iconv_t __cd_in;
|
||||||
_IO_iconv_t __cd_out;
|
_IO_iconv_t __cd_out;
|
||||||
};
|
};
|
||||||
|
@ -476,7 +476,6 @@ extern const struct _IO_jump_t _IO_streambuf_jumps;
|
|||||||
extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden;
|
extern const struct _IO_jump_t _IO_old_proc_jumps attribute_hidden;
|
||||||
extern const struct _IO_jump_t _IO_str_jumps attribute_hidden;
|
extern const struct _IO_jump_t _IO_str_jumps attribute_hidden;
|
||||||
extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden;
|
extern const struct _IO_jump_t _IO_wstr_jumps attribute_hidden;
|
||||||
extern const struct _IO_codecvt __libio_codecvt attribute_hidden;
|
|
||||||
extern int _IO_do_write (FILE *, const char *, size_t);
|
extern int _IO_do_write (FILE *, const char *, size_t);
|
||||||
libc_hidden_proto (_IO_do_write)
|
libc_hidden_proto (_IO_do_write)
|
||||||
extern int _IO_new_do_write (FILE *, const char *, size_t);
|
extern int _IO_new_do_write (FILE *, const char *, size_t);
|
||||||
@ -932,4 +931,32 @@ IO_validate_vtable (const struct _IO_jump_t *vtable)
|
|||||||
return vtable;
|
return vtable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Character set conversion. */
|
||||||
|
|
||||||
|
enum __codecvt_result
|
||||||
|
{
|
||||||
|
__codecvt_ok,
|
||||||
|
__codecvt_partial,
|
||||||
|
__codecvt_error,
|
||||||
|
__codecvt_noconv
|
||||||
|
};
|
||||||
|
|
||||||
|
enum __codecvt_result __libio_codecvt_out (struct _IO_codecvt *,
|
||||||
|
__mbstate_t *,
|
||||||
|
const wchar_t *,
|
||||||
|
const wchar_t *,
|
||||||
|
const wchar_t **, char *,
|
||||||
|
char *, char **)
|
||||||
|
attribute_hidden;
|
||||||
|
enum __codecvt_result __libio_codecvt_in (struct _IO_codecvt *,
|
||||||
|
__mbstate_t *,
|
||||||
|
const char *, const char *,
|
||||||
|
const char **, wchar_t *,
|
||||||
|
wchar_t *, wchar_t **)
|
||||||
|
attribute_hidden;
|
||||||
|
int __libio_codecvt_encoding (struct _IO_codecvt *) attribute_hidden;
|
||||||
|
int __libio_codecvt_length (struct _IO_codecvt *, __mbstate_t *,
|
||||||
|
const char *, const char *, size_t)
|
||||||
|
attribute_hidden;
|
||||||
|
|
||||||
#endif /* libioP.h. */
|
#endif /* libioP.h. */
|
||||||
|
@ -72,7 +72,7 @@ _IO_wdo_write (FILE *fp, const wchar_t *data, size_t to_do)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Now convert from the internal format into the external buffer. */
|
/* Now convert from the internal format into the external buffer. */
|
||||||
result = (*cc->__codecvt_do_out) (cc, &fp->_wide_data->_IO_state,
|
result = __libio_codecvt_out (cc, &fp->_wide_data->_IO_state,
|
||||||
data, data + to_do, &new_data,
|
data, data + to_do, &new_data,
|
||||||
write_ptr,
|
write_ptr,
|
||||||
buf_end,
|
buf_end,
|
||||||
@ -140,7 +140,7 @@ _IO_wfile_underflow (FILE *fp)
|
|||||||
fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
|
fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
|
||||||
fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
|
fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
|
||||||
fp->_wide_data->_IO_buf_base;
|
fp->_wide_data->_IO_buf_base;
|
||||||
status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
|
status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
|
||||||
fp->_IO_read_ptr, fp->_IO_read_end,
|
fp->_IO_read_ptr, fp->_IO_read_end,
|
||||||
&read_stop,
|
&read_stop,
|
||||||
fp->_wide_data->_IO_read_ptr,
|
fp->_wide_data->_IO_read_ptr,
|
||||||
@ -266,7 +266,7 @@ _IO_wfile_underflow (FILE *fp)
|
|||||||
naccbuf += to_copy;
|
naccbuf += to_copy;
|
||||||
from = accbuf;
|
from = accbuf;
|
||||||
}
|
}
|
||||||
status = (*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
|
status = __libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
|
||||||
from, to, &read_ptr_copy,
|
from, to, &read_ptr_copy,
|
||||||
fp->_wide_data->_IO_read_end,
|
fp->_wide_data->_IO_read_end,
|
||||||
fp->_wide_data->_IO_buf_end,
|
fp->_wide_data->_IO_buf_end,
|
||||||
@ -372,7 +372,7 @@ _IO_wfile_underflow_mmap (FILE *fp)
|
|||||||
fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
|
fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
|
||||||
fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
|
fp->_wide_data->_IO_read_base = fp->_wide_data->_IO_read_ptr =
|
||||||
fp->_wide_data->_IO_buf_base;
|
fp->_wide_data->_IO_buf_base;
|
||||||
(*cd->__codecvt_do_in) (cd, &fp->_wide_data->_IO_state,
|
__libio_codecvt_in (cd, &fp->_wide_data->_IO_state,
|
||||||
fp->_IO_read_ptr, fp->_IO_read_end,
|
fp->_IO_read_ptr, fp->_IO_read_end,
|
||||||
&read_stop,
|
&read_stop,
|
||||||
fp->_wide_data->_IO_read_ptr,
|
fp->_wide_data->_IO_read_ptr,
|
||||||
@ -495,7 +495,7 @@ _IO_wfile_sync (FILE *fp)
|
|||||||
struct _IO_codecvt *cv = fp->_codecvt;
|
struct _IO_codecvt *cv = fp->_codecvt;
|
||||||
off64_t new_pos;
|
off64_t new_pos;
|
||||||
|
|
||||||
int clen = (*cv->__codecvt_do_encoding) (cv);
|
int clen = __libio_codecvt_encoding (cv);
|
||||||
|
|
||||||
if (clen > 0)
|
if (clen > 0)
|
||||||
/* It is easy, a fixed number of input bytes are used for each
|
/* It is easy, a fixed number of input bytes are used for each
|
||||||
@ -511,7 +511,7 @@ _IO_wfile_sync (FILE *fp)
|
|||||||
size_t wnread = (fp->_wide_data->_IO_read_ptr
|
size_t wnread = (fp->_wide_data->_IO_read_ptr
|
||||||
- fp->_wide_data->_IO_read_base);
|
- fp->_wide_data->_IO_read_base);
|
||||||
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
|
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
|
||||||
nread = (*cv->__codecvt_do_length) (cv, &fp->_wide_data->_IO_state,
|
nread = __libio_codecvt_length (cv, &fp->_wide_data->_IO_state,
|
||||||
fp->_IO_read_base,
|
fp->_IO_read_base,
|
||||||
fp->_IO_read_end, wnread);
|
fp->_IO_read_end, wnread);
|
||||||
fp->_IO_read_ptr = fp->_IO_read_base + nread;
|
fp->_IO_read_ptr = fp->_IO_read_base + nread;
|
||||||
@ -548,7 +548,7 @@ adjust_wide_data (FILE *fp, bool do_convert)
|
|||||||
{
|
{
|
||||||
struct _IO_codecvt *cv = fp->_codecvt;
|
struct _IO_codecvt *cv = fp->_codecvt;
|
||||||
|
|
||||||
int clen = (*cv->__codecvt_do_encoding) (cv);
|
int clen = __libio_codecvt_encoding (cv);
|
||||||
|
|
||||||
/* Take the easy way out for constant length encodings if we don't need to
|
/* Take the easy way out for constant length encodings if we don't need to
|
||||||
convert. */
|
convert. */
|
||||||
@ -565,7 +565,7 @@ adjust_wide_data (FILE *fp, bool do_convert)
|
|||||||
{
|
{
|
||||||
|
|
||||||
fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
|
fp->_wide_data->_IO_last_state = fp->_wide_data->_IO_state;
|
||||||
status = (*cv->__codecvt_do_in) (cv, &fp->_wide_data->_IO_state,
|
status = __libio_codecvt_in (cv, &fp->_wide_data->_IO_state,
|
||||||
fp->_IO_read_base, fp->_IO_read_ptr,
|
fp->_IO_read_base, fp->_IO_read_ptr,
|
||||||
&read_stop,
|
&read_stop,
|
||||||
fp->_wide_data->_IO_read_base,
|
fp->_wide_data->_IO_read_base,
|
||||||
@ -648,7 +648,7 @@ do_ftell_wide (FILE *fp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct _IO_codecvt *cv = fp->_codecvt;
|
struct _IO_codecvt *cv = fp->_codecvt;
|
||||||
int clen = (*cv->__codecvt_do_encoding) (cv);
|
int clen = __libio_codecvt_encoding (cv);
|
||||||
|
|
||||||
if (!unflushed_writes)
|
if (!unflushed_writes)
|
||||||
{
|
{
|
||||||
@ -663,7 +663,7 @@ do_ftell_wide (FILE *fp)
|
|||||||
|
|
||||||
size_t delta = wide_read_ptr - wide_read_base;
|
size_t delta = wide_read_ptr - wide_read_base;
|
||||||
__mbstate_t state = fp->_wide_data->_IO_last_state;
|
__mbstate_t state = fp->_wide_data->_IO_last_state;
|
||||||
nread = (*cv->__codecvt_do_length) (cv, &state,
|
nread = __libio_codecvt_length (cv, &state,
|
||||||
fp->_IO_read_base,
|
fp->_IO_read_base,
|
||||||
fp->_IO_read_end, delta);
|
fp->_IO_read_end, delta);
|
||||||
offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
|
offset -= fp->_IO_read_end - fp->_IO_read_base - nread;
|
||||||
@ -688,8 +688,7 @@ do_ftell_wide (FILE *fp)
|
|||||||
enum __codecvt_result status;
|
enum __codecvt_result status;
|
||||||
|
|
||||||
__mbstate_t state = fp->_wide_data->_IO_last_state;
|
__mbstate_t state = fp->_wide_data->_IO_last_state;
|
||||||
status = (*cv->__codecvt_do_out) (cv, &state,
|
status = __libio_codecvt_out (cv, &state, in, in + delta, &in,
|
||||||
in, in + delta, &in,
|
|
||||||
out, out + outsize, &outstop);
|
out, out + outsize, &outstop);
|
||||||
|
|
||||||
/* We don't check for __codecvt_partial because it can be
|
/* We don't check for __codecvt_partial because it can be
|
||||||
@ -801,7 +800,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
|
|||||||
find out which position in the external buffer corresponds to
|
find out which position in the external buffer corresponds to
|
||||||
the current position in the internal buffer. */
|
the current position in the internal buffer. */
|
||||||
cv = fp->_codecvt;
|
cv = fp->_codecvt;
|
||||||
clen = (*cv->__codecvt_do_encoding) (cv);
|
clen = __libio_codecvt_encoding (cv);
|
||||||
|
|
||||||
if (mode != 0 || !was_writing)
|
if (mode != 0 || !was_writing)
|
||||||
{
|
{
|
||||||
@ -819,7 +818,7 @@ _IO_wfile_seekoff (FILE *fp, off64_t offset, int dir, int mode)
|
|||||||
delta = (fp->_wide_data->_IO_read_ptr
|
delta = (fp->_wide_data->_IO_read_ptr
|
||||||
- fp->_wide_data->_IO_read_base);
|
- fp->_wide_data->_IO_read_base);
|
||||||
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
|
fp->_wide_data->_IO_state = fp->_wide_data->_IO_last_state;
|
||||||
nread = (*cv->__codecvt_do_length) (cv,
|
nread = __libio_codecvt_length (cv,
|
||||||
&fp->_wide_data->_IO_state,
|
&fp->_wide_data->_IO_state,
|
||||||
fp->_IO_read_base,
|
fp->_IO_read_base,
|
||||||
fp->_IO_read_end, delta);
|
fp->_IO_read_end, delta);
|
||||||
|
Reference in New Issue
Block a user