Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
hiredis
Commits
e40daec2
Commit
e40daec2
authored
Jul 10, 2011
by
Pieter Noordhuis
Browse files
Merge branch 'printf-width'
parents
5def8643
dad240f0
Changes
2
Hide whitespace changes
Inline
Side-by-side
hiredis.c
View file @
e40daec2
...
...
@@ -770,33 +770,79 @@ int redisvFormatCommand(char **target, const char *format, va_list ap) {
while
(
*
_p
!=
'\0'
&&
isdigit
(
*
_p
))
_p
++
;
}
/* Modifiers */
if
(
*
_p
!=
'\0'
)
{
if
(
*
_p
==
'h'
||
*
_p
==
'l'
)
{
/* Allow a single repetition for these modifiers */
if
(
_p
[
0
]
==
_p
[
1
])
_p
++
;
_p
++
;
/* Copy va_list before consuming with va_arg */
va_copy
(
_cpy
,
ap
);
/* Integer conversion (without modifiers) */
if
(
strchr
(
"diouxX"
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
int
);
goto
fmt_valid
;
}
/* Double conversion (without modifiers) */
if
(
strchr
(
"eEfFgGaA"
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
double
);
goto
fmt_valid
;
}
/* Size: char */
if
(
_p
[
0
]
==
'h'
&&
_p
[
1
]
==
'h'
)
{
_p
+=
2
;
if
(
*
_p
!=
'\0'
&&
strchr
(
"diouxX"
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
int
);
/* char gets promoted to int */
goto
fmt_valid
;
}
goto
fmt_invalid
;
}
/* Size: short */
if
(
_p
[
0
]
==
'h'
)
{
_p
+=
1
;
if
(
*
_p
!=
'\0'
&&
strchr
(
"diouxX"
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
int
);
/* short gets promoted to int */
goto
fmt_valid
;
}
goto
fmt_invalid
;
}
/* Conversion specifier */
if
(
*
_p
!=
'\0'
&&
strchr
(
"diouxXeEfFgGaA"
,
*
_p
)
!=
NULL
)
{
_l
=
(
_p
+
1
)
-
c
;
if
(
_l
<
sizeof
(
_format
)
-
2
)
{
memcpy
(
_format
,
c
,
_l
);
_format
[
_l
]
=
'\0'
;
va_copy
(
_cpy
,
ap
);
newarg
=
sdscatvprintf
(
curarg
,
_format
,
_cpy
);
va_end
(
_cpy
);
/* Update current position (note: outer blocks
* increment c twice so compensate here) */
c
=
_p
-
1
;
/* Size: long long */
if
(
_p
[
0
]
==
'l'
&&
_p
[
1
]
==
'l'
)
{
_p
+=
2
;
if
(
*
_p
!=
'\0'
&&
strchr
(
"diouxX"
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
long
long
);
goto
fmt_valid
;
}
goto
fmt_invalid
;
}
/* Size: long */
if
(
_p
[
0
]
==
'l'
)
{
_p
+=
1
;
if
(
*
_p
!=
'\0'
&&
strchr
(
"diouxX"
,
*
_p
)
!=
NULL
)
{
va_arg
(
ap
,
long
);
goto
fmt_valid
;
}
goto
fmt_invalid
;
}
fmt_invalid:
va_end
(
_cpy
);
goto
err
;
fmt_valid:
_l
=
(
_p
+
1
)
-
c
;
if
(
_l
<
sizeof
(
_format
)
-
2
)
{
memcpy
(
_format
,
c
,
_l
);
_format
[
_l
]
=
'\0'
;
newarg
=
sdscatvprintf
(
curarg
,
_format
,
_cpy
);
/* Update current position (note: outer blocks
* increment c twice so compensate here) */
c
=
_p
-
1
;
}
/* Consume and discard vararg */
va_arg
(
ap
,
void
)
;
va_end
(
_cpy
);
break
;
}
}
...
...
test.c
View file @
e40daec2
...
...
@@ -142,29 +142,43 @@ static void test_format_commands(void) {
len
==
4
+
4
+
(
3
+
2
)
+
4
+
(
1
+
2
)
+
4
+
(
1
+
2
));
free
(
cmd
);
test
(
"Format command with printf-delegation (long long): "
);
len
=
redisFormatCommand
(
&
cmd
,
"key:%08lld"
,
1234ll
);
test_cond
(
strncmp
(
cmd
,
"*1
\r\n
$12
\r\n
key:00001234
\r\n
"
,
len
)
==
0
&&
len
==
4
+
5
+
(
12
+
2
));
free
(
cmd
);
test
(
"Format command with printf-delegation (float): "
);
len
=
redisFormatCommand
(
&
cmd
,
"v:%06.1f"
,
12
.
34
f
);
test_cond
(
strncmp
(
cmd
,
"*1
\r\n
$8
\r\n
v:0012.3
\r\n
"
,
len
)
==
0
&&
len
==
4
+
4
+
(
8
+
2
));
free
(
cmd
);
test
(
"Format command with printf-delegation and extra interpolation: "
);
len
=
redisFormatCommand
(
&
cmd
,
"key:%d %b"
,
1234
,
"foo"
,
3
);
test_cond
(
strncmp
(
cmd
,
"*2
\r\n
$8
\r\n
key:1234
\r\n
$3
\r\n
foo
\r\n
"
,
len
)
==
0
&&
len
==
4
+
4
+
(
8
+
2
)
+
4
+
(
3
+
2
));
free
(
cmd
);
test
(
"Format command with wrong printf format and extra interpolation: "
);
/* Vararg width depends on the type. These tests make sure that the
* width is correctly determined using the format and subsequent varargs
* can correctly be interpolated. */
#define INTEGER_WIDTH_TEST(fmt, type) do { \
type value = 123; \
test("Format command with printf-delegation (" #type "): "); \
len = redisFormatCommand(&cmd,"key:%08" fmt " str:%s", value, "hello"); \
test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:00000123\r\n$9\r\nstr:hello\r\n",len) == 0 && \
len == 4+5+(12+2)+4+(9+2)); \
free(cmd); \
} while(0)
#define FLOAT_WIDTH_TEST(type) do { \
type value = 123.0; \
test("Format command with printf-delegation (" #type "): "); \
len = redisFormatCommand(&cmd,"key:%08.3f str:%s", value, "hello"); \
test_cond(strncmp(cmd,"*2\r\n$12\r\nkey:0123.000\r\n$9\r\nstr:hello\r\n",len) == 0 && \
len == 4+5+(12+2)+4+(9+2)); \
free(cmd); \
} while(0)
INTEGER_WIDTH_TEST
(
"d"
,
int
);
INTEGER_WIDTH_TEST
(
"hhd"
,
char
);
INTEGER_WIDTH_TEST
(
"hd"
,
short
);
INTEGER_WIDTH_TEST
(
"ld"
,
long
);
INTEGER_WIDTH_TEST
(
"lld"
,
long
long
);
INTEGER_WIDTH_TEST
(
"u"
,
unsigned
int
);
INTEGER_WIDTH_TEST
(
"hhu"
,
unsigned
char
);
INTEGER_WIDTH_TEST
(
"hu"
,
unsigned
short
);
INTEGER_WIDTH_TEST
(
"lu"
,
unsigned
long
);
INTEGER_WIDTH_TEST
(
"llu"
,
unsigned
long
long
);
FLOAT_WIDTH_TEST
(
float
);
FLOAT_WIDTH_TEST
(
double
);
test
(
"Format command with invalid printf format: "
);
len
=
redisFormatCommand
(
&
cmd
,
"key:%08p %b"
,
1234
,
"foo"
,
3
);
test_cond
(
strncmp
(
cmd
,
"*2
\r\n
$6
\r\n
key:8p
\r\n
$3
\r\n
foo
\r\n
"
,
len
)
==
0
&&
len
==
4
+
4
+
(
6
+
2
)
+
4
+
(
3
+
2
));
free
(
cmd
);
test_cond
(
len
==
-
1
);
const
char
*
argv
[
3
];
argv
[
0
]
=
"SET"
;
...
...
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