Skip to content

Commit 7c3ba84

Browse files
authored
Merge pull request #4429 from larsewi/CFE-2686
CFE-2686: Policy function format() no longer truncates strings lager than 4KiB
2 parents 368d737 + 0043008 commit 7c3ba84

File tree

3 files changed

+53
-26
lines changed

3 files changed

+53
-26
lines changed

libpromises/evalfunction.c

Lines changed: 14 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5334,9 +5334,7 @@ static FnCallResult FnCallSort(EvalContext *ctx, ARG_UNUSED const Policy *policy
53345334

53355335
static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *policy, const FnCall *fp, const Rlist *finalargs)
53365336
{
5337-
char id[CF_BUFSIZE];
5338-
5339-
snprintf(id, CF_BUFSIZE, "built-in FnCall %s-arg", fp->name);
5337+
const char *const id = "built-in FnCall format-arg";
53405338

53415339
/* We need to check all the arguments, ArgTemplate does not check varadic functions */
53425340
for (const Rlist *arg = finalargs; arg; arg = arg->next)
@@ -5348,14 +5346,14 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
53485346
}
53495347
}
53505348

5351-
if (!finalargs)
5349+
if (finalargs == NULL)
53525350
{
53535351
return FnFailure();
53545352
}
53555353

53565354
char *format = RlistScalarValue(finalargs);
53575355

5358-
if (!format)
5356+
if (format == NULL)
53595357
{
53605358
return FnFailure();
53615359
}
@@ -5366,12 +5364,12 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
53665364
char check_buffer[CF_BUFSIZE];
53675365
Buffer *buf = BufferNew();
53685366

5369-
if (check)
5367+
if (check != NULL)
53705368
{
53715369
BufferAppend(buf, format, check - format);
53725370
Seq *s;
53735371

5374-
while (check &&
5372+
while (check != NULL &&
53755373
(s = StringMatchCaptures("^(%%|%[^diouxXeEfFgGaAcsCSpnm%]*?[diouxXeEfFgGaAcsCSpnm])([^%]*)(.*)$", check, false)))
53765374
{
53775375
{
@@ -5385,7 +5383,7 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
53855383
{
53865384
// "%%" in format string
53875385
}
5388-
else if (rp)
5386+
else if (rp != NULL)
53895387
{
53905388
data = RlistScalarValue(rp);
53915389
rp = rp->next;
@@ -5401,8 +5399,6 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
54015399
char piece[CF_BUFSIZE];
54025400
memset(piece, 0, CF_BUFSIZE);
54035401

5404-
// CfOut(OUTPUT_LEVEL_INFORM, "", "format: processing format piece = '%s' with data '%s'", format_piece, percent ? "%" : data);
5405-
54065402
const char bad_modifiers[] = "hLqjzt";
54075403
const size_t length = strlen(bad_modifiers);
54085404
for (int b = 0; b < length; b++)
@@ -5418,43 +5414,38 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
54185414
}
54195415
}
54205416

5421-
if (strrchr(format_piece, 'd') || strrchr(format_piece, 'o') || strrchr(format_piece, 'x'))
5417+
if (strrchr(format_piece, 'd') != NULL || strrchr(format_piece, 'o') != NULL || strrchr(format_piece, 'x') != NULL)
54225418
{
54235419
long x = 0;
54245420
sscanf(data, "%ld%s", &x, piece); // we don't care about the remainder and will overwrite it
54255421
snprintf(piece, CF_BUFSIZE, format_piece, x);
54265422
BufferAppend(buf, piece, strlen(piece));
5427-
// CfOut(OUTPUT_LEVEL_INFORM, "", "format: appending int format piece = '%s' with data '%s'", format_piece, data);
54285423
}
54295424
else if (percent)
54305425
{
54315426
// "%%" -> "%"
54325427
BufferAppend(buf, "%", 1);
5433-
// CfOut(OUTPUT_LEVEL_INFORM, "", "format: appending int format piece = '%s' with data '%s'", format_piece, data);
54345428
}
5435-
else if (strrchr(format_piece, 'f'))
5429+
else if (strrchr(format_piece, 'f') != NULL)
54365430
{
54375431
double x = 0;
54385432
sscanf(data, "%lf%s", &x, piece); // we don't care about the remainder and will overwrite it
54395433
snprintf(piece, CF_BUFSIZE, format_piece, x);
54405434
BufferAppend(buf, piece, strlen(piece));
5441-
// CfOut(OUTPUT_LEVEL_INFORM, "", "format: appending float format piece = '%s' with data '%s'", format_piece, data);
54425435
}
5443-
else if (strrchr(format_piece, 's'))
5436+
else if (strrchr(format_piece, 's') != NULL)
54445437
{
5445-
snprintf(piece, CF_BUFSIZE, format_piece, data);
5446-
BufferAppend(buf, piece, strlen(piece));
5447-
// CfOut(OUTPUT_LEVEL_INFORM, "", "format: appending string format piece = '%s' with data '%s'", format_piece, data);
5438+
BufferAppendF(buf, format_piece, data);
54485439
}
5449-
else if (strrchr(format_piece, 'S'))
5440+
else if (strrchr(format_piece, 'S') != NULL)
54505441
{
54515442
char *found_format_spec = NULL;
54525443
char format_rewrite[CF_BUFSIZE];
54535444

54545445
strlcpy(format_rewrite, format_piece, CF_BUFSIZE);
54555446
found_format_spec = strrchr(format_rewrite, 'S');
54565447

5457-
if (found_format_spec)
5448+
if (found_format_spec != NULL)
54585449
{
54595450
*found_format_spec = 's';
54605451
}
@@ -5473,9 +5464,8 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
54735464
{
54745465
Writer *w = StringWriter();
54755466
JsonWriteCompact(w, value);
5476-
snprintf(piece, CF_BUFSIZE, format_rewrite, StringWriterData(w));
5467+
BufferAppendF(buf, format_rewrite, StringWriterData(w));
54775468
WriterClose(w);
5478-
BufferAppend(buf, piece, strlen(piece));
54795469
}
54805470
else // it might be a list reference
54815471
{
@@ -5498,9 +5488,8 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
54985488
}
54995489
WriterWrite(w, " }");
55005490

5501-
snprintf(piece, CF_BUFSIZE, format_rewrite, StringWriterData(w));
5491+
BufferAppendF(buf, format_rewrite, StringWriterData(w));
55025492
WriterClose(w);
5503-
BufferAppend(buf, piece, strlen(piece));
55045493
}
55055494
else // whatever this is, it's not a list reference or a data container
55065495
{
@@ -5516,7 +5505,6 @@ static FnCallResult FnCallFormat(EvalContext *ctx, ARG_UNUSED const Policy *poli
55165505
{
55175506
char error[] = "(unhandled format)";
55185507
BufferAppend(buf, error, strlen(error));
5519-
// CfOut(OUTPUT_LEVEL_INFORM, "", "format: error appending unhandled format piece = '%s' with data '%s'", format_piece, data);
55205508
}
55215509
}
55225510
else
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Test bug fix
2+
# Former bug truncates strings greater than 4096 bytes
3+
# There is no reason for format() to truncate strings
4+
5+
body common control
6+
{
7+
inputs => { "../../default.cf.sub" };
8+
bundlesequence => { default("$(this.promise_filename)") };
9+
version => "1.0";
10+
}
11+
12+
##########################################################
13+
14+
bundle agent test {
15+
vars:
16+
"str" string => format('%s', 'Hello, everyone! This is the LONGEST TEXT EVER! I was inspired by the various other longest texts ever on the internet, and I wanted to make my own. So here it is! This is going to be a WORLD RECORD! This is actually my third attempt at doing this. The first time, I didnt save it. The second time, the Neocities editor crashed. Now Im writing this in Notepad, then copying it into the Neocities editor instead of typing it directly in the Neocities editor to avoid crashing. It sucks that my past two attempts are gone now. Those actually got pretty long. Not the longest, but still pretty long. I hope this one wont get lost somehow. Anyways, lets talk about WAFFLES! I like waffles. Waffles are cool. Waffles is a funny word. Theres a Teen Titans Go episode called Waffles where the word Waffles is said a hundred-something times. Its pretty annoying. Theres also a Teen Titans Go episode about Pig Latin. Dont know what Pig Latin is? Its a language where you take all the consonants before the first vowel, move them to the end, and add -ay to the end. If the word begins with a vowel, you just add -way to the end. For example, Waffles becomes Afflesway. Ive been speaking Pig Latin fluently since the fourth grade, so it surprised me when I saw the episode for the first time. I speak Pig Latin with my sister sometimes. Its pretty fun. I like speaking it in public so that everyone around us gets confused. Thats never actually happened before, but if it ever does, twill be pretty funny. By the way, twill is a word I invented recently, and its a contraction of it will. I really hope it gains popularity in the near future, because twill is WAY more fun than saying itll. Itll is too boring. Nobody likes boring. This is nowhere near being the longest text ever, but eventually it will be! I might still be writing this a decade later, who knows? But right now, its not very long. But Ill just keep writing until it is the longest! Have you ever heard the song Dau Dau by Awesome Scampis? Its an amazing song. Look it up on YouTube! I play that song all the time around my sister! It drives her crazy, and I love it. Another way I like driving my sister crazy is by speaking my own made up language to her. She hates the languages I make! The only language that we both speak besides English is Pig Latin. I think you already knew that. Whatever. I think Im gonna go for now. Bye! Hi, Im back now. Im gonna contribute more to this soon-to-be giant wall of text. I just realised I have a giant stuffed frog on my bed. I forgot his name. Im pretty sure it was something stupid though. I think it was FROG in Morse Code or something. Morse Code is cool. I know a bit of it, but Im not very good at it. Im also not very good at French. I barely know anything in French, and my pronunciation probably sucks. But Im learning it, at least. Im also learning Esperanto. Its this language that was made up by some guy a long time ago to be the universal language. A lot of people speak it. I am such a language nerd. Half of this text is probably gonna be about languages. But hey, as long as its long! Ha, get it? As LONG as its LONG? Im so funny, right? No, Im not. I should probably get some sleep. Goodnight! Hello, Im back again. I basically have only two interests nowadays: languages and furries. What? Oh, sorry, I thought you knew I was a furry. Haha, oops. Anyway, yeah, Im a furry, but since Im a young furry, I cant really do as much as I would like to do in the fandom. When Im older, I would like to have a fursuit, go to furry conventions, all that stuff. But for now I can only dream of that. Sorry you had to deal with me talking about furries, but Im honestly very desperate for this to be the longest text ever. Last night I was watching nothing but fursuit unboxings. I think I need help. This one time, me and my mom were going to go to a furry Christmas party, but we didnt end up going because of the fact that there was alcohol on the premises, and that she didnt wanna have to be a mom dragging her son through a crowd of furries. Both of those reasons were understandable. Okay, hopefully I wont have to talk about furries anymore. I dont care if youre a furry reading this right now, I just dont wanna have to torture everyone else.');
17+
"list" slist => { $(str) };
18+
"list_str" string => format('%S', "list");
19+
"container" data => parsejson(' ["$(str)"] ');
20+
"container_str" string => format('%S', "container");
21+
}
22+
23+
bundle agent check {
24+
methods:
25+
"check" usebundle => dcs_check_state(test,
26+
"$(this.promise_filename).expected.json",
27+
$(this.promise_filename));
28+
}

0 commit comments

Comments
 (0)