Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
F
fmt
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Libraries
fmt
Commits
6570dc31
Commit
6570dc31
authored
Nov 19, 2017
by
Victor Zverovich
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Disallow formatting of multibyte strings into a wide buffer (#606)
parent
3851994a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
29 additions
and
59 deletions
+29
-59
include/fmt/format.h
include/fmt/format.h
+27
-53
test/util-test.cc
test/util-test.cc
+2
-6
No files found.
include/fmt/format.h
View file @
6570dc31
...
...
@@ -1112,7 +1112,7 @@ enum type {
INT
,
UINT
,
LONG_LONG
,
ULONG_LONG
,
BOOL
,
CHAR
,
LAST_INTEGER_TYPE
=
CHAR
,
// followed by floating-point types.
DOUBLE
,
LONG_DOUBLE
,
LAST_NUMERIC_TYPE
=
LONG_DOUBLE
,
CSTRING
,
STRING
,
TSTRING
,
POINTER
,
CUSTOM
CSTRING
,
STRING
,
POINTER
,
CUSTOM
};
constexpr
bool
is_integral
(
type
t
)
{
...
...
@@ -1189,10 +1189,10 @@ template <> constexpr type get_type<unsigned char *>() { return CSTRING; }
template
<
>
constexpr
type
get_type
<
const
unsigned
char
*>
()
{
return
CSTRING
;
}
template
<
>
constexpr
type
get_type
<
std
::
string
>
()
{
return
STRING
;
}
template
<
>
constexpr
type
get_type
<
string_view
>
()
{
return
STRING
;
}
template
<
>
constexpr
type
get_type
<
wchar_t
*>
()
{
return
T
STRING
;
}
template
<
>
constexpr
type
get_type
<
const
wchar_t
*>
()
{
return
T
STRING
;
}
template
<
>
constexpr
type
get_type
<
std
::
wstring
>
()
{
return
T
STRING
;
}
template
<
>
constexpr
type
get_type
<
wstring_view
>
()
{
return
T
STRING
;
}
template
<
>
constexpr
type
get_type
<
wchar_t
*>
()
{
return
C
STRING
;
}
template
<
>
constexpr
type
get_type
<
const
wchar_t
*>
()
{
return
C
STRING
;
}
template
<
>
constexpr
type
get_type
<
std
::
wstring
>
()
{
return
STRING
;
}
template
<
>
constexpr
type
get_type
<
wstring_view
>
()
{
return
STRING
;
}
template
<
>
constexpr
type
get_type
<
void
*>
()
{
return
POINTER
;
}
template
<
>
constexpr
type
get_type
<
const
void
*>
()
{
return
POINTER
;
}
template
<
>
constexpr
type
get_type
<
std
::
nullptr_t
>
()
{
return
POINTER
;
}
...
...
@@ -1225,10 +1225,9 @@ class value {
double
double_value
;
long
double
long_double_value
;
const
void
*
pointer
;
string_value
<
char
>
string
;
string_value
<
char
_type
>
string
;
string_value
<
signed
char
>
sstring
;
string_value
<
unsigned
char
>
ustring
;
string_value
<
char_type
>
tstring
;
custom_value
<
char_type
>
custom
;
};
...
...
@@ -1271,18 +1270,16 @@ class value {
}
#endif
value
(
char
*
s
)
{
set
<
CSTRING
>
(
string
.
value
,
s
);
}
value
(
const
char
*
s
)
{
set
<
CSTRING
>
(
string
.
value
,
s
);
}
value
(
signed
char
*
s
)
{
set
<
CSTRING
>
(
sstring
.
value
,
s
);
}
value
(
const
signed
char
*
s
)
{
set
<
CSTRING
>
(
sstring
.
value
,
s
);
}
value
(
unsigned
char
*
s
)
{
set
<
CSTRING
>
(
ustring
.
value
,
s
);
}
value
(
const
unsigned
char
*
s
)
{
set
<
CSTRING
>
(
ustring
.
value
,
s
);
}
value
(
string_view
s
)
{
set_string
(
s
);
}
value
(
const
std
::
string
&
s
)
{
set_string
(
s
);
}
value
(
wstring_view
s
)
{
set_wstring
(
s
);
}
value
(
const
std
::
wstring
&
s
)
{
set_wstring
(
s
);
}
value
(
wchar_t
*
s
)
{
set_wstring
(
wstring_view
(
s
));
}
value
(
const
wchar_t
*
s
)
{
set_wstring
(
wstring_view
(
s
));
}
// Formatting of wide strings into a narrow buffer and multibyte strings
// into a wide buffer is disallowed (https://github.com/fmtlib/fmt/pull/606).
value
(
char_type
*
s
)
{
set
<
CSTRING
>
(
string
.
value
,
s
);
}
value
(
const
char_type
*
s
)
{
set
<
CSTRING
>
(
string
.
value
,
s
);
}
value
(
signed
char
*
s
)
{
set_cstring
(
sstring
.
value
,
s
);
}
value
(
const
signed
char
*
s
)
{
set_cstring
(
sstring
.
value
,
s
);
}
value
(
unsigned
char
*
s
)
{
set_cstring
(
ustring
.
value
,
s
);
}
value
(
const
unsigned
char
*
s
)
{
set_cstring
(
ustring
.
value
,
s
);
}
value
(
basic_string_view
<
char_type
>
s
)
{
set_string
(
s
);
}
value
(
const
std
::
basic_string
<
char_type
>
&
s
)
{
set_string
(
s
);
}
// Formatting of arbitrary pointers is disallowed. If you want to output a
// pointer cast it to "void *" or "const void *". In particular, this forbids
...
...
@@ -1338,12 +1335,11 @@ class value {
string
.
size
=
value
.
size
();
}
template
<
typename
T
>
void
set_wstring
(
const
T
&
value
)
{
require_wchar
<
char_type
>
();
static_assert
(
get_type
<
T
>
()
==
TSTRING
,
"invalid type"
);
tstring
.
value
=
value
.
data
();
tstring
.
size
=
value
.
size
();
template
<
typename
T
,
typename
U
>
constexpr
void
set_cstring
(
T
&
field
,
const
U
*
str
)
{
static_assert
(
std
::
is_same
<
char
,
char_type
>::
value
,
"incompatible string types"
);
set
<
CSTRING
>
(
field
,
str
);
}
// Formats an argument of a custom type, such as a user-defined class.
...
...
@@ -1439,10 +1435,8 @@ constexpr typename std::result_of<Visitor(int)>::type
case
internal
:
:
CSTRING
:
return
vis
(
arg
.
value_
.
string
.
value
);
case
internal
:
:
STRING
:
return
vis
(
string_view
(
arg
.
value_
.
string
.
value
,
arg
.
value_
.
string
.
size
));
case
internal
:
:
TSTRING
:
return
vis
(
basic_string_view
<
Char
>
(
arg
.
value_
.
tstring
.
value
,
arg
.
value_
.
t
string
.
size
));
arg
.
value_
.
string
.
value
,
arg
.
value_
.
string
.
size
));
case
internal
:
:
POINTER
:
return
vis
(
arg
.
value_
.
pointer
);
case
internal
:
:
CUSTOM
:
...
...
@@ -1902,22 +1896,6 @@ class arg_formatter_base {
writer_
.
write_int
(
reinterpret_cast
<
uintptr_t
>
(
p
),
spec_
);
}
template
<
typename
StrChar
>
typename
std
::
enable_if
<
std
::
is_same
<
Char
,
wchar_t
>::
value
&&
std
::
is_same
<
StrChar
,
wchar_t
>::
value
>::
type
write_str
(
basic_string_view
<
StrChar
>
value
)
{
writer_
.
write_str
(
value
,
spec_
);
}
template
<
typename
StrChar
>
typename
std
::
enable_if
<
!
std
::
is_same
<
Char
,
wchar_t
>::
value
||
!
std
::
is_same
<
StrChar
,
wchar_t
>::
value
>::
type
write_str
(
basic_string_view
<
StrChar
>
)
{
// Do nothing.
}
protected:
basic_writer
<
Char
>
&
writer
()
{
return
writer_
;
}
format_specs
&
spec
()
{
return
spec_
;
}
...
...
@@ -1926,9 +1904,9 @@ class arg_formatter_base {
writer_
.
write_str
(
string_view
(
value
?
"true"
:
"false"
),
spec_
);
}
void
write
(
const
c
har
*
value
)
{
writer_
.
write_str
(
string_view
(
value
,
value
!=
0
?
std
::
strlen
(
value
)
:
0
),
spec_
);
void
write
(
const
C
har
*
value
)
{
writer_
.
write_str
(
basic_string_view
<
Char
>
(
value
,
value
!=
0
?
std
::
char_traits
<
Char
>::
length
(
value
)
:
0
),
spec_
);
}
public:
...
...
@@ -1985,20 +1963,16 @@ class arg_formatter_base {
*
out
=
internal
::
char_traits
<
Char
>::
cast
(
value
);
}
void
operator
()(
const
c
har
*
value
)
{
void
operator
()(
const
C
har
*
value
)
{
if
(
spec_
.
type_
==
'p'
)
return
write_pointer
(
value
);
write
(
value
);
}
void
operator
()(
string_view
value
)
{
void
operator
()(
basic_string_view
<
Char
>
value
)
{
writer_
.
write_str
(
value
,
spec_
);
}
void
operator
()(
basic_string_view
<
wchar_t
>
value
)
{
write_str
(
value
);
}
void
operator
()(
const
void
*
value
)
{
if
(
spec_
.
type_
&&
spec_
.
type_
!=
'p'
)
report_unknown_type
(
spec_
.
type_
,
"pointer"
);
...
...
test/util-test.cc
View file @
6570dc31
...
...
@@ -563,13 +563,9 @@ TEST(UtilTest, StringArg) {
char
*
str
=
str_data
;
const
char
*
cstr
=
str
;
CHECK_ARG_
(
char
,
cstr
,
str
);
CHECK_ARG_
(
wchar_t
,
cstr
,
str
);
CHECK_ARG
(
cstr
);
string_view
sref
(
str
);
CHECK_ARG_
(
char
,
sref
,
std
::
string
(
str
));
CHECK_ARG_
(
wchar_t
,
sref
,
std
::
string
(
str
));
CHECK_ARG
(
sref
);
}
TEST
(
UtilTest
,
WStringArg
)
{
...
...
@@ -578,8 +574,8 @@ TEST(UtilTest, WStringArg) {
const
wchar_t
*
cstr
=
str
;
fmt
::
wstring_view
sref
(
str
);
CHECK_ARG_
(
wchar_t
,
sref
,
str
);
CHECK_ARG_
(
wchar_t
,
sref
,
cstr
);
CHECK_ARG_
(
wchar_t
,
cstr
,
str
);
CHECK_ARG_
(
wchar_t
,
cstr
,
cstr
);
CHECK_ARG_
(
wchar_t
,
sref
,
std
::
wstring
(
str
));
CHECK_ARG_
(
wchar_t
,
sref
,
fmt
::
wstring_view
(
str
));
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment