buf: Fix possible infinite loop in EscapeString, VSnprintf
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after
2010-09-01 13:51:35 -04:00
# include <config.h>
# include "internal.h"
# include "testutils.h"
2012-12-04 12:04:07 +00:00
# include "virbuffer.h"
buf: Fix possible infinite loop in EscapeString, VSnprintf
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after
2010-09-01 13:51:35 -04:00
2013-06-07 17:10:28 +02:00
# define VIR_FROM_THIS VIR_FROM_NONE
2020-01-14 08:04:29 +01:00
struct testBufAddStrData {
const char * data ;
const char * expect ;
2020-01-14 08:04:14 +01:00
const char * arg ;
2020-01-14 08:04:29 +01:00
} ;
2019-10-14 14:45:03 +02:00
static int testBufAutoIndent ( const void * data G_GNUC_UNUSED )
2011-10-20 15:48:47 -06:00
{
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) bufinit = VIR_BUFFER_INITIALIZER ;
2021-03-11 08:16:13 +01:00
virBuffer * buf = & bufinit ;
2011-10-20 15:48:47 -06:00
const char expected [ ] =
2022-02-11 15:48:02 +01:00
" 1 \n 2 \n 3 \n 4 \n 5 \n 6 \n 7 \n & \n 8 \n 9 \n 10 \n "
" ' 11' \n '' \\ ''12' \n ' \" 13' \n '' \n " ;
2020-01-14 08:04:54 +01:00
g_autofree char * result = NULL ;
2011-10-20 15:48:47 -06:00
int ret = 0 ;
2019-10-24 12:51:24 +02:00
if ( virBufferGetIndent ( buf ) ! = 0 | |
2019-10-24 12:29:12 +02:00
virBufferGetEffectiveIndent ( buf ) ! = 0 ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Wrong indentation " ) ;
2011-10-20 15:48:47 -06:00
ret = - 1 ;
}
virBufferAdjustIndent ( buf , 3 ) ;
2012-06-08 13:50:23 -06:00
if ( STRNEQ ( virBufferCurrentContent ( buf ) , " " ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Wrong content " ) ;
2012-06-08 13:50:23 -06:00
ret = - 1 ;
}
2019-10-24 12:51:24 +02:00
if ( virBufferGetIndent ( buf ) ! = 3 | |
2019-10-24 14:25:59 +02:00
virBufferGetEffectiveIndent ( buf ) ! = 3 ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Wrong indentation " ) ;
2011-10-20 15:48:47 -06:00
ret = - 1 ;
}
virBufferAdjustIndent ( buf , - 2 ) ;
2019-10-24 12:51:24 +02:00
if ( virBufferGetIndent ( buf ) ! = 1 | |
2019-10-24 14:25:59 +02:00
virBufferGetEffectiveIndent ( buf ) ! = 1 ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Wrong indentation " ) ;
2011-10-20 15:48:47 -06:00
ret = - 1 ;
}
virBufferAdjustIndent ( buf , - 3 ) ;
2019-10-24 12:51:24 +02:00
if ( virBufferGetIndent ( buf ) ! = 0 | |
2019-10-24 12:29:12 +02:00
virBufferGetEffectiveIndent ( buf ) ! = 0 ) {
2019-10-24 09:25:20 +02:00
VIR_TEST_DEBUG ( " Indentation level not truncated " ) ;
2011-10-20 15:48:47 -06:00
ret = - 1 ;
}
2019-10-24 09:25:20 +02:00
virBufferAdjustIndent ( buf , 3 ) ;
2011-10-20 15:48:47 -06:00
virBufferFreeAndReset ( buf ) ;
2019-10-24 12:51:24 +02:00
if ( virBufferGetIndent ( buf ) ! = 0 | |
2019-10-24 14:25:59 +02:00
virBufferGetEffectiveIndent ( buf ) ! = 0 ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Reset didn't clear indentation " ) ;
2011-10-20 15:48:47 -06:00
ret = - 1 ;
}
virBufferAdjustIndent ( buf , 2 ) ;
virBufferAddLit ( buf , " 1 " ) ;
2012-06-08 13:50:23 -06:00
if ( STRNEQ ( virBufferCurrentContent ( buf ) , " 1 " ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Wrong content " ) ;
2012-06-08 13:50:23 -06:00
ret = - 1 ;
}
2019-10-24 12:51:24 +02:00
if ( virBufferGetIndent ( buf ) ! = 2 | |
2019-10-24 12:29:12 +02:00
virBufferGetEffectiveIndent ( buf ) ! = 0 ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Wrong indentation " ) ;
2011-10-20 15:48:47 -06:00
ret = - 1 ;
}
virBufferAddLit ( buf , " \n " ) ;
virBufferAdd ( buf , " " " 2 \n " , - 1 ) ; /* Extra "" appeases syntax-check */
virBufferAddChar ( buf , ' 3 ' ) ;
virBufferAddChar ( buf , ' \n ' ) ;
virBufferAsprintf ( buf , " %d " , 4 ) ;
virBufferAsprintf ( buf , " %c " , ' \n ' ) ;
virBufferStrcat ( buf , " 5 " , " \n " , " 6 \n " , NULL ) ;
virBufferEscapeString ( buf , " %s \n " , " 7 " ) ;
virBufferEscapeString ( buf , " %s \n " , " & " ) ;
virBufferEscapeSexpr ( buf , " %s " , " 8 \n " ) ;
virBufferURIEncodeString ( buf , " 9 " ) ;
virBufferAddChar ( buf , ' \n ' ) ;
virBufferEscapeShell ( buf , " 10 " ) ;
virBufferAddChar ( buf , ' \n ' ) ;
virBufferEscapeShell ( buf , " 11 " ) ;
virBufferAddChar ( buf , ' \n ' ) ;
2022-02-11 15:48:02 +01:00
virBufferEscapeShell ( buf , " '12 " ) ;
virBufferAddChar ( buf , ' \n ' ) ;
virBufferEscapeShell ( buf , " \" 13 " ) ;
virBufferAddChar ( buf , ' \n ' ) ;
virBufferEscapeShell ( buf , " " ) ;
virBufferAddChar ( buf , ' \n ' ) ;
2011-10-20 15:48:47 -06:00
result = virBufferContentAndReset ( buf ) ;
tests: Use virTestCompareToString() more
Instead of using:
if (STRNEQ(a, b)) {
virTestDifference(stderr, a, b);
...
}
we can use:
if (virTestCompareToString(a, b) < ) {
...
}
Generated by the following spatch:
@@
expression a, b;
@@
- if (STRNEQ(a, b)) {
+ if (virTestCompareToString(a, b) < 0) {
...
- virTestDifference(stderr, a, b);
...
}
and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).
However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-11-30 09:57:49 +01:00
if ( virTestCompareToString ( expected , result ) < 0 ) {
2011-10-20 15:48:47 -06:00
ret = - 1 ;
}
return ret ;
}
2019-10-14 14:45:03 +02:00
static int testBufTrim ( const void * data G_GNUC_UNUSED )
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
{
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) bufinit = VIR_BUFFER_INITIALIZER ;
2021-03-11 08:16:13 +01:00
virBuffer * buf = NULL ;
2020-01-14 08:04:54 +01:00
g_autofree char * result = NULL ;
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
const char * expected = " a,b " ;
2013-06-18 17:52:00 +02:00
2020-02-02 20:26:38 +01:00
virBufferTrim ( buf , " " ) ;
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
buf = & bufinit ;
virBufferAddLit ( buf , " a; " ) ;
2020-02-02 20:26:38 +01:00
virBufferTrim ( buf , " " ) ;
virBufferTrim ( buf , " " ) ;
2020-02-02 20:17:20 +01:00
virBufferTrimLen ( buf , 1 ) ;
virBufferTrimLen ( buf , 5 ) ;
virBufferTrimLen ( buf , 2 ) ;
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
virBufferAddLit ( buf , " ,b,, " ) ;
2020-02-02 20:26:38 +01:00
virBufferTrim ( buf , NULL ) ;
virBufferTrim ( buf , " b " ) ;
virBufferTrim ( buf , " ,, " ) ;
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
result = virBufferContentAndReset ( buf ) ;
tests: Use virTestCompareToString() more
Instead of using:
if (STRNEQ(a, b)) {
virTestDifference(stderr, a, b);
...
}
we can use:
if (virTestCompareToString(a, b) < ) {
...
}
Generated by the following spatch:
@@
expression a, b;
@@
- if (STRNEQ(a, b)) {
+ if (virTestCompareToString(a, b) < 0) {
...
- virTestDifference(stderr, a, b);
...
}
and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).
However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-11-30 09:57:49 +01:00
if ( virTestCompareToString ( expected , result ) < 0 ) {
2020-07-02 23:20:17 -04:00
return - 1 ;
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
}
2020-07-02 23:20:17 -04:00
return 0 ;
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
}
2020-01-14 08:04:14 +01:00
static int
testBufTrimChars ( const void * opaque )
{
const struct testBufAddStrData * data = opaque ;
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) buf = VIR_BUFFER_INITIALIZER ;
2020-01-14 08:04:14 +01:00
g_autofree char * actual = NULL ;
virBufferAddStr ( & buf , data - > data ) ;
virBufferTrimChars ( & buf , data - > arg ) ;
if ( ! ( actual = virBufferContentAndReset ( & buf ) ) ) {
VIR_TEST_DEBUG ( " buf is empty " ) ;
return - 1 ;
}
tests: Use virTestCompareToString() more
Instead of using:
if (STRNEQ(a, b)) {
virTestDifference(stderr, a, b);
...
}
we can use:
if (virTestCompareToString(a, b) < ) {
...
}
Generated by the following spatch:
@@
expression a, b;
@@
- if (STRNEQ(a, b)) {
+ if (virTestCompareToString(a, b) < 0) {
...
- virTestDifference(stderr, a, b);
...
}
and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).
However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-11-30 09:57:49 +01:00
if ( virTestCompareToString ( data - > expect , actual ) < 0 ) {
2020-01-14 08:04:14 +01:00
return - 1 ;
}
return 0 ;
}
2019-10-14 14:45:03 +02:00
static int testBufAddBuffer ( const void * data G_GNUC_UNUSED )
2015-02-19 10:56:58 +01:00
{
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) buf1 = VIR_BUFFER_INITIALIZER ;
g_auto ( virBuffer ) buf2 = VIR_BUFFER_INITIALIZER ;
g_auto ( virBuffer ) buf3 = VIR_BUFFER_INITIALIZER ;
2020-01-14 08:04:54 +01:00
g_autofree char * result = NULL ;
2015-02-19 10:56:58 +01:00
const char * expected = \
" A long time ago, in a galaxy far, \n " \
2017-11-03 13:09:47 +01:00
" far away... \n " \
" It is a period of civil war. \n " \
" Rebel spaceships, striking \n " \
" from a hidden base, have won \n " \
" their first victory against \n " \
" the evil Galactic Empire. \n " \
" During the battle, rebel \n " \
" spies managed to steal secret \n " \
" plans to the Empire's \n " \
" ultimate weapon, the DEATH \n " \
" STAR, an armored space \n " \
" station with enough power to \n " \
2015-02-19 10:56:58 +01:00
" destroy an entire planet. \n " ;
if ( virBufferUse ( & buf1 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf1 already in use " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
if ( virBufferUse ( & buf2 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf2 already in use " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
if ( virBufferUse ( & buf3 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf3 already in use " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
virBufferAdjustIndent ( & buf1 , 2 ) ;
virBufferAddLit ( & buf1 , " A long time ago, in a galaxy far, \n " ) ;
virBufferAddLit ( & buf1 , " far away... \n " ) ;
virBufferAdjustIndent ( & buf2 , 4 ) ;
virBufferAddLit ( & buf2 , " It is a period of civil war. \n " ) ;
virBufferAddLit ( & buf2 , " Rebel spaceships, striking \n " ) ;
virBufferAddLit ( & buf2 , " from a hidden base, have won \n " ) ;
virBufferAddLit ( & buf2 , " their first victory against \n " ) ;
virBufferAddLit ( & buf2 , " the evil Galactic Empire. \n " ) ;
virBufferAdjustIndent ( & buf3 , 2 ) ;
virBufferAddLit ( & buf3 , " During the battle, rebel \n " ) ;
virBufferAddLit ( & buf3 , " spies managed to steal secret \n " ) ;
virBufferAddLit ( & buf3 , " plans to the Empire's \n " ) ;
virBufferAddLit ( & buf3 , " ultimate weapon, the DEATH \n " ) ;
virBufferAddLit ( & buf3 , " STAR, an armored space \n " ) ;
virBufferAddLit ( & buf3 , " station with enough power to \n " ) ;
virBufferAddLit ( & buf3 , " destroy an entire planet. \n " ) ;
if ( ! virBufferUse ( & buf1 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Error adding to buf1 " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
if ( ! virBufferUse ( & buf2 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Error adding to buf2 " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
if ( ! virBufferUse ( & buf3 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " Error adding to buf3 " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
virBufferAddBuffer ( & buf2 , & buf3 ) ;
if ( ! virBufferUse ( & buf2 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf2 cleared mistakenly " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
if ( virBufferUse ( & buf3 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf3 is not clear even though it should be " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
virBufferAddBuffer ( & buf1 , & buf2 ) ;
if ( ! virBufferUse ( & buf1 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf1 cleared mistakenly " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
if ( virBufferUse ( & buf2 ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf2 is not clear even though it should be " ) ;
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
result = virBufferContentAndReset ( & buf1 ) ;
tests: Use virTestCompareToString() more
Instead of using:
if (STRNEQ(a, b)) {
virTestDifference(stderr, a, b);
...
}
we can use:
if (virTestCompareToString(a, b) < ) {
...
}
Generated by the following spatch:
@@
expression a, b;
@@
- if (STRNEQ(a, b)) {
+ if (virTestCompareToString(a, b) < 0) {
...
- virTestDifference(stderr, a, b);
...
}
and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).
However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-11-30 09:57:49 +01:00
if ( virTestCompareToString ( expected , result ) < 0 ) {
2020-07-02 23:20:17 -04:00
return - 1 ;
2015-02-19 10:56:58 +01:00
}
2020-07-02 23:20:17 -04:00
return 0 ;
2015-02-19 10:56:58 +01:00
}
2015-03-24 10:53:29 +01:00
static int
2020-01-14 08:05:56 +01:00
testBufAddStr ( const void * opaque )
2015-03-24 10:53:29 +01:00
{
const struct testBufAddStrData * data = opaque ;
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) buf = VIR_BUFFER_INITIALIZER ;
2020-01-14 08:04:54 +01:00
g_autofree char * actual = NULL ;
2015-03-24 10:53:29 +01:00
virBufferAddLit ( & buf , " <c> \n " ) ;
virBufferAdjustIndent ( & buf , 2 ) ;
virBufferAddStr ( & buf , data - > data ) ;
virBufferAdjustIndent ( & buf , - 2 ) ;
virBufferAddLit ( & buf , " </c> " ) ;
if ( ! ( actual = virBufferContentAndReset ( & buf ) ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf is empty " ) ;
2020-01-14 08:10:25 +01:00
return - 1 ;
2015-03-24 10:53:29 +01:00
}
tests: Use virTestCompareToString() more
Instead of using:
if (STRNEQ(a, b)) {
virTestDifference(stderr, a, b);
...
}
we can use:
if (virTestCompareToString(a, b) < ) {
...
}
Generated by the following spatch:
@@
expression a, b;
@@
- if (STRNEQ(a, b)) {
+ if (virTestCompareToString(a, b) < 0) {
...
- virTestDifference(stderr, a, b);
...
}
and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).
However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-11-30 09:57:49 +01:00
if ( virTestCompareToString ( data - > expect , actual ) < 0 ) {
2020-01-14 08:10:25 +01:00
return - 1 ;
2015-03-24 10:53:29 +01:00
}
2020-01-14 08:10:25 +01:00
return 0 ;
2015-03-24 10:53:29 +01:00
}
virBuffer: add way to trim back extra text
I'm tired of writing:
bool sep = false;
while (...) {
if (sep)
virBufferAddChar(buf, ',');
sep = true;
virBufferAdd(buf, str);
}
This makes it easier, allowing one to write:
while (...)
virBufferAsprintf(buf, "%s,", str);
virBufferTrim(buf, ",", -1);
to trim any remaining comma.
* src/util/buf.h (virBufferTrim): Declare.
* src/util/buf.c (virBufferTrim): New function.
* tests/virbuftest.c (testBufTrim): Test it.
2012-05-18 16:36:59 -06:00
2015-03-30 12:41:40 +02:00
static int
2020-01-14 08:05:56 +01:00
testBufEscapeStr ( const void * opaque )
2015-03-30 12:41:40 +02:00
{
const struct testBufAddStrData * data = opaque ;
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) buf = VIR_BUFFER_INITIALIZER ;
2020-01-14 08:04:54 +01:00
g_autofree char * actual = NULL ;
2015-03-30 12:41:40 +02:00
virBufferAddLit ( & buf , " <c> \n " ) ;
virBufferAdjustIndent ( & buf , 2 ) ;
virBufferEscapeString ( & buf , " <el>%s</el> \n " , data - > data ) ;
virBufferAdjustIndent ( & buf , - 2 ) ;
virBufferAddLit ( & buf , " </c> " ) ;
if ( ! ( actual = virBufferContentAndReset ( & buf ) ) ) {
2015-04-23 13:38:00 -04:00
VIR_TEST_DEBUG ( " buf is empty " ) ;
2020-01-14 08:10:25 +01:00
return - 1 ;
2015-03-30 12:41:40 +02:00
}
tests: Use virTestCompareToString() more
Instead of using:
if (STRNEQ(a, b)) {
virTestDifference(stderr, a, b);
...
}
we can use:
if (virTestCompareToString(a, b) < ) {
...
}
Generated by the following spatch:
@@
expression a, b;
@@
- if (STRNEQ(a, b)) {
+ if (virTestCompareToString(a, b) < 0) {
...
- virTestDifference(stderr, a, b);
...
}
and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).
However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-11-30 09:57:49 +01:00
if ( virTestCompareToString ( data - > expect , actual ) < 0 ) {
2020-01-14 08:10:25 +01:00
return - 1 ;
2015-03-30 12:41:40 +02:00
}
2020-01-14 08:10:25 +01:00
return 0 ;
2015-03-30 12:41:40 +02:00
}
2017-05-12 14:26:09 +02:00
static int
testBufEscapeRegex ( const void * opaque )
{
const struct testBufAddStrData * data = opaque ;
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) buf = VIR_BUFFER_INITIALIZER ;
2020-01-14 08:04:54 +01:00
g_autofree char * actual = NULL ;
2017-05-12 14:26:09 +02:00
virBufferEscapeRegex ( & buf , " %s " , data - > data ) ;
if ( ! ( actual = virBufferContentAndReset ( & buf ) ) ) {
2019-02-21 16:26:44 +01:00
VIR_TEST_DEBUG ( " testBufEscapeRegex: buf is empty " ) ;
2020-01-14 08:10:25 +01:00
return - 1 ;
2017-05-12 14:26:09 +02:00
}
tests: Use virTestCompareToString() more
Instead of using:
if (STRNEQ(a, b)) {
virTestDifference(stderr, a, b);
...
}
we can use:
if (virTestCompareToString(a, b) < ) {
...
}
Generated by the following spatch:
@@
expression a, b;
@@
- if (STRNEQ(a, b)) {
+ if (virTestCompareToString(a, b) < 0) {
...
- virTestDifference(stderr, a, b);
...
}
and its variations (STRNEQ_NULLABLE() instead of STRNEQ(), then
in some cases variables passed to STRNEQ() are in reversed order
when compared to virTestCompareToString()).
However, coccinelle failed to recognize the pattern in
testNWFilterEBIPTablesAllTeardown() so I had to fix it manually.
Also, I manually fixed testFormat() in tests/sockettest.c as I
didn't bother writing another spatch rule just for that.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Jonathon Jongsma <jjongsma@redhat.com>
2022-11-30 09:57:49 +01:00
if ( virTestCompareToString ( data - > expect , actual ) < 0 ) {
2020-01-14 08:10:25 +01:00
return - 1 ;
2017-05-12 14:26:09 +02:00
}
2020-01-14 08:10:25 +01:00
return 0 ;
2017-05-12 14:26:09 +02:00
}
2017-03-09 17:02:19 +01:00
static int
2019-10-14 14:45:03 +02:00
testBufSetIndent ( const void * opaque G_GNUC_UNUSED )
2017-03-09 17:02:19 +01:00
{
2020-07-02 19:35:41 -04:00
g_auto ( virBuffer ) buf = VIR_BUFFER_INITIALIZER ;
2020-01-14 08:04:54 +01:00
g_autofree char * actual = NULL ;
2017-03-09 17:02:19 +01:00
virBufferSetIndent ( & buf , 11 ) ;
virBufferAddLit ( & buf , " test \n " ) ;
virBufferSetIndent ( & buf , 2 ) ;
virBufferAddLit ( & buf , " test2 \n " ) ;
if ( ! ( actual = virBufferContentAndReset ( & buf ) ) )
2020-01-14 08:10:25 +01:00
return - 1 ;
2017-03-09 17:02:19 +01:00
if ( STRNEQ ( actual , " test \n test2 \n " ) ) {
2019-05-03 10:31:02 +02:00
VIR_TEST_DEBUG ( " testBufSetIndent: expected indent not set " ) ;
2020-01-14 08:10:25 +01:00
return - 1 ;
2017-03-09 17:02:19 +01:00
}
2020-01-14 08:10:25 +01:00
return 0 ;
2017-03-09 17:02:19 +01:00
}
2019-02-21 16:37:50 +01:00
/* Result of this shows up only in valgrind or similar */
static int
2019-10-14 14:45:03 +02:00
testBufferAutoclean ( const void * opaque G_GNUC_UNUSED )
2019-02-21 16:37:50 +01:00
{
2019-10-15 14:47:50 +02:00
g_auto ( virBuffer ) buf = VIR_BUFFER_INITIALIZER ;
2019-02-21 16:37:50 +01:00
virBufferAddLit ( & buf , " test test test \n " ) ;
return 0 ;
}
buf: Fix possible infinite loop in EscapeString, VSnprintf
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after
2010-09-01 13:51:35 -04:00
static int
2011-04-29 10:21:20 -06:00
mymain ( void )
buf: Fix possible infinite loop in EscapeString, VSnprintf
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after
2010-09-01 13:51:35 -04:00
{
int ret = 0 ;
2019-10-24 12:18:13 +02:00
# define DO_TEST(msg, cb) \
2017-11-03 13:09:47 +01:00
do { \
2019-10-24 12:18:13 +02:00
if ( virTestRun ( " Buf: " msg , cb , NULL ) < 0 ) \
2017-11-03 13:09:47 +01:00
ret = - 1 ; \
buf: Fix possible infinite loop in EscapeString, VSnprintf
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after
2010-09-01 13:51:35 -04:00
} while ( 0 )
2019-10-24 12:18:13 +02:00
DO_TEST ( " Auto-indentation " , testBufAutoIndent ) ;
DO_TEST ( " Trim " , testBufTrim ) ;
DO_TEST ( " AddBuffer " , testBufAddBuffer ) ;
DO_TEST ( " set indent " , testBufSetIndent ) ;
DO_TEST ( " autoclean " , testBufferAutoclean ) ;
buf: Fix possible infinite loop in EscapeString, VSnprintf
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after
2010-09-01 13:51:35 -04:00
2020-01-14 08:06:34 +01:00
# define DO_TEST_ADD_STR(_data, _expect) \
2017-11-03 13:09:47 +01:00
do { \
2020-01-14 08:06:34 +01:00
struct testBufAddStrData info = { . data = _data , . expect = _expect } ; \
2017-11-03 13:09:47 +01:00
if ( virTestRun ( " Buf: AddStr " , testBufAddStr , & info ) < 0 ) \
ret = - 1 ; \
2015-03-24 10:53:29 +01:00
} while ( 0 )
DO_TEST_ADD_STR ( " " , " <c> \n </c> " ) ;
DO_TEST_ADD_STR ( " <a/> " , " <c> \n <a/></c> " ) ;
DO_TEST_ADD_STR ( " <a/> \n " , " <c> \n <a/> \n </c> " ) ;
DO_TEST_ADD_STR ( " <b> \n <a/> \n </b> \n " , " <c> \n <b> \n <a/> \n </b> \n </c> " ) ;
2020-01-14 08:06:34 +01:00
# define DO_TEST_ESCAPE(_data, _expect) \
2017-11-03 13:09:47 +01:00
do { \
2020-01-14 08:06:34 +01:00
struct testBufAddStrData info = { . data = _data , . expect = _expect } ; \
2016-05-26 17:01:50 +02:00
if ( virTestRun ( " Buf: EscapeStr " , testBufEscapeStr , & info ) < 0 ) \
2017-11-03 13:09:47 +01:00
ret = - 1 ; \
2015-03-30 12:41:40 +02:00
} while ( 0 )
DO_TEST_ESCAPE ( " <td></td><td></td> " ,
" <c> \n <el><td></td><td></td></el> \n </c> " ) ;
DO_TEST_ESCAPE ( " \007 \" && \" \x15 " ,
" <c> \n <el>"&&"</el> \n </c> " ) ;
DO_TEST_ESCAPE ( " ,,'..',, " ,
" <c> \n <el>,,'..',,</el> \n </c> " ) ;
DO_TEST_ESCAPE ( " \x01 \x01 \x02 \x03 \x05 \x08 " ,
" <c> \n <el></el> \n </c> " ) ;
2020-01-14 08:06:34 +01:00
# define DO_TEST_ESCAPE_REGEX(_data, _expect) \
2017-11-03 13:09:47 +01:00
do { \
2020-01-14 08:06:34 +01:00
struct testBufAddStrData info = { . data = _data , . expect = _expect } ; \
2017-11-03 13:09:47 +01:00
if ( virTestRun ( " Buf: EscapeRegex " , testBufEscapeRegex , & info ) < 0 ) \
ret = - 1 ; \
2017-05-12 14:26:09 +02:00
} while ( 0 )
DO_TEST_ESCAPE_REGEX ( " noescape " , " noescape " ) ;
DO_TEST_ESCAPE_REGEX ( " ^$.|?*+()[]{} \\ " ,
" \\ ^ \\ $ \\ . \\ | \\ ? \\ * \\ + \\ ( \\ ) \\ [ \\ ] \\ { \\ } \\ \\ " ) ;
2020-01-14 08:04:14 +01:00
# define DO_TEST_TRIM_CHARS(_data, _arg, _expect) \
do { \
struct testBufAddStrData info = { . data = _data , . expect = _expect , . arg = _arg } ; \
if ( virTestRun ( " Buf: Trim: " # _data , testBufTrimChars , & info ) < 0 ) \
ret = - 1 ; \
} while ( 0 )
DO_TEST_TRIM_CHARS ( " Trimmm " , " m " , " Tri " ) ;
DO_TEST_TRIM_CHARS ( " -abcd-efgh-- " , " - " , " -abcd-efgh " ) ;
DO_TEST_TRIM_CHARS ( " -hABC-efgh-- " , " -h " , " -hABC-efg " ) ;
2014-03-17 10:38:38 +01:00
return ret = = 0 ? EXIT_SUCCESS : EXIT_FAILURE ;
buf: Fix possible infinite loop in EscapeString, VSnprintf
The current code will go into an infinite loop if the printf generated
string is >= 1000, AND exactly 1 character smaller than the amount of free
space in the buffer. When this happens, we are dropped into the loop body,
but nothing will actually change, because count == (buf->size - buf->use - 1),
and virBufferGrow returns unchanged if count < (buf->size - buf->use)
Fix this by removing the '- 1' bit from 'size'. The *nprintf functions handle
the NULL byte for us anyways, so we shouldn't need to manually accommodate
for it.
Here's a bug where we are actually hitting this issue:
https://bugzilla.redhat.com/show_bug.cgi?id=602772
v2: Eric's improvements: while -> if (), remove extra va_list variable,
make sure we report buffer error if snprintf fails
v3: Add tests/virbuftest which reproduces the infinite loop before this
patch, works correctly after
2010-09-01 13:51:35 -04:00
}
2017-03-29 16:45:42 +02:00
VIR_TEST_MAIN ( mymain )