<meta http-equiv="Content-Type" content="text/html; charset=GB18030"><div><br></div><div><div><br></div><div><br></div><div style="font-size: 12px;font-family: Arial Narrow;padding:2px 0 2px 0;">------------------ Original ------------------</div><div style="font-size: 12px;background:#efefef;padding:8px;"><div><b>From:</b>                                                                                                                        "dovecot"                                                                                    <dovecot-request@dovecot.org>;</div><div><b>Date:</b> Tue, Mar 30, 2021 11:55 PM</div><div><b>To:</b> "dovecot"<dovecot@dovecot.org>;<wbr></div><div></div><div><b>Subject:</b> dovecot Digest, Vol 215, Issue 77</div></div><div><br></div>Send dovecot mailing list submissions to<br> dovecot@dovecot.org<br><br>To subscribe or unsubscribe via the World Wide Web, visit<br>      https://dovecot.org/mailman/listinfo/dovecot<br>or, via email, send a message with subject or body 'help' to<br>    dovecot-request@dovecot.org<br><br>You can reach the person managing the list at<br>  dovecot-owner@dovecot.org<br><br>When replying, please edit your Subject line so it is more specific<br>than "Re: Contents of dovecot digest..."<br><br><br>Today's Topics:<br><br>   1. special characters in FTS Solr fail (piuma@piumalab.org)<br>   2. json_parse_number broken by compiler optimization<br>      (Christian Ehrhardt)<br>   3. Re: json_parse_number broken by compiler optimization (Aki Tuomi)<br><br><br>----------------------------------------------------------------------<br><br>Message: 1<br>Date: Tue, 30 Mar 2021 16:20:56 +0200<br>From: "piuma@piumalab.org" <piuma@piumalab.org><br>To: dovecot@dovecot.org<br>Subject: special characters in FTS Solr fail<br>Message-ID: <3c779646-e2fc-9f51-063c-a8816450dbfd@piumalab.org><br>Content-Type: text/plain; charset="utf-8"<br><br>Hi, I want to report a bug about searching.<br>My dovecot version is 2.3.10.1 (a3d0e1171) and use Solr 7.7.2 for full text search.<br>The issue appear when try to search using solr special characters. For example<br>if I have emails with the subject that contain the only character "(" open<br>parenthesis, then try to search it I receive zero results.<br><br>In the Solr log seems the "(" is correctly excaped as "\(":<br><br>2021-03-30 15:14:20.304 INFO  (qtp333683827-20) [   x:dovecot] o.a.s.c.S.Request<br>[dovecot]  webapp=/solr path=/select<br>params={q={!lucene+q.op%3DAND}subject:\(&fl=uid,score&sort=uid+asc&fq=%2Bbox:6fff5821c5a2365df4060000d0d97f83+%2Buser:titolare01@kendama.it&rows=631&wt=xml}<br>hits=0 status=0 QTime=2<br><br>I provide dovecot-sysreport as attachment.<br><br>Best regards<br>   Danilo<br>-------------- next part --------------<br>A non-text attachment was scrubbed...<br>Name: dovecot-sysreport-pecbox02.par-tec.it-1617116347.tar.gz<br>Type: application/gzip<br>Size: 7395 bytes<br>Desc: not available<br>URL: <https://dovecot.org/pipermail/dovecot/attachments/20210330/08492366/attachment-0001.gz><br><br>------------------------------<br><br>Message: 2<br>Date: Tue, 30 Mar 2021 17:53:27 +0200<br>From: Christian Ehrhardt <christian.ehrhardt@canonical.com><br>To: dovecot@dovecot.org<br>Subject: json_parse_number broken by compiler optimization<br>Message-ID:<br>     <CAATJJ0JB9e4cZrS=hiM0r=yF4-Fz693ZK3qLa41L-rYVfy8QbQ@mail.gmail.com><br>Content-Type: text/plain; charset="UTF-8"<br><br>Hi,<br>the recent Ubuntu (re)builds uncovered an issue with dovecot 1:2.3.13+dfsg1-1<br>build log: https://launchpadlibrarian.net/529849650/buildlog_ubuntu-hirsute-amd64.dovecot_1%3A2.3.13+dfsg1-1build1_BUILDING.txt.gz<br>A coworker tried 2.3.14 but got the same result.<br><br>What fails is the json_parser build time test like:<br>  test-json-parser.c:161: Assert(#25) failed:<br>null_strcmp(json_output[pos].value, value) == 0<br><br>I was looking into that a bit more and what I found is that it is<br>dependent on the new toolchain<br>of gcc 10.2.0-1.<br><br>Not all calls to json_parse_* fail, e.g. the first one looks all good and passes<br>I was iterating the tests using a report function defined like<br><br>(gdb) define repcon<br>>c<br>>p pos<br>>p json_output[pos].type<br>>p type<br>>p json_output[pos].value<br>>p value<br>>call null_strcmp(json_output[pos].value, value)<br>>end<br><br>The first one to be bad was:<br>Breakpoint 2, test_json_parser_success (full_size=<optimized out>) at<br>test-json-parser.c:161<br>161 test_assert_idx(null_strcmp(json_output[pos].value, value) == 0, pos);<br>$84 = 25<br>$85 = JSON_TYPE_NUMBER<br>$86 = JSON_TYPE_NUMBER<br>$87 = 0x555555633b25 "-12.456"<br>$88 = 0x555555693110 ""<br>$89 = 45<br><br>Earlier and later parsing was happy, for example<br><br>Breakpoint 2, test_json_parser_success (full_size=<optimized out>) at<br>test-json-parser.c:161<br>161 test_assert_idx(null_strcmp(json_output[pos].value, value) == 0, pos);<br>$90 = 27<br>$91 = JSON_TYPE_NUMBER<br>$92 = JSON_TYPE_NUMBER<br>$93 = 0x555555633b32 "12.456e9"<br>$94 = 0x555555693110 "12.456e9"<br>$95 = 0<br>(gdb)<br><br><br>We have two things we compare here.<br>1. json_output[] which is a static define and for this value is<br>   67 ????{ JSON_TYPE_NUMBER, "-12.456" },<br>2. the return value that json_parse_next returns.<br>   25 ????"  \"sub2\":-12.456,\n"<br>  148 ????????????????ret = json_parse_next(parser, &type, &value);<br><br>I tried a non negative number and got success which is suspicious<br><br>Breakpoint 5, test_json_parser_success (full_size=<optimized out>) at<br>test-json-parser.c:164<br>164 test_assert_idx(null_strcmp(json_output[pos].value, value) == 0, pos);<br>$122 = 25<br>$123 = JSON_TYPE_NUMBER<br>$124 = JSON_TYPE_NUMBER<br>$125 = 0x555555633b2c "12.456"<br>$126 = 0x555555693110 "12.456"<br>$127 = 0<br>(gdb)<br><br><br>Also the return value otherwise LGTM, it is recognized as a number:<br>540 } else if ((ret = json_parse_number(parser, value_r)) >= 0) {<br>(gdb) n<br>541 *type_r = JSON_TYPE_NUMBER;<br><br>So parsing worked one might think, but the value was not set.<br><br>(gdb) p *value_r<br>$833 = 0x555555693110 ""<br><br>It turns out json_parse_number is too optimized.<br>Too optimized for debugging further into json_parse_number.<br>But also optimization is causing the issue.<br>With -O0 or -O1 it works fine, even putting the lower optimization<br>level just around json_parse_number it is enough to avoid the issue.<br><br><br>Not a fix but "avoidance" for now:<br><br>--- a/src/lib/json-parser.c<br>+++ b/src/lib/json-parser.c<br>@@ -386,6 +386,8 @@ static int json_parse_int(struct json_pa<br>  return 1;<br> }<br><br>+#pragma GCC push_options<br>+#pragma GCC optimize ("-O0")<br> static int json_parse_number(struct json_parser *parser, const char **value_r)<br> {<br>  int ret;<br>@@ -415,6 +417,7 @@ static int json_parse_number(struct json<br>  *value_r = str_c(parser->value);<br>  return 1;<br> }<br>+#pragma GCC pop_options<br><br> static int json_parse_atom(struct json_parser *parser, const char *atom)<br> {<br><br><br>I was trying to see what happened and tracked each str_append_c<br>that happened inside json_parse_number.<br>A breakpoint on str_append_c and backtraces showed that we clearly do the<br>"right" parsing. From the backtraces I've seen it does (just from positions):<br><br>For example<br>(gdb) bt<br>#0  str_append_c (chr=<optimized out>, str=0x5555556930d0) at str.h:44<br>#1  json_parse_digits (parser=<optimized out>) at json-parser.c:366<br>=> that is a digit<br><br>It does "- digit digit dot digit digit digit"<br><br>This perfectly matches the input value, but still the result stays empty:<br>(gdb) p (char*)(str->data)<br>$738 = 0x555555693110 ""<br><br>In comparison - when parsing the latter 12.456e9 which works I see two<br>odd things:<br>1. the value isn't cleared despite<br>    str_truncate(parser->value, 0);<br>   at the beginning of json_parse_number<br>2. the value (this time) is read exactly as I assumed<br><br>Breakpoint 17, json_parse_number (value_r=0x7fffffffe1a0,<br>parser=0x555555692ee0) at json-parser.c:394<br>394 str_truncate(parser->value, 0);<br>Breakpoint 18, str_append_c (chr=<optimized out>, str=0x5555556930d0)<br>at str.h:44<br>44 buffer_append_c(str, chr);<br>(gdb) p (char*)(str->data)<br>$741 = 0x555555693110 "sub3"<br><br>^^ not cleared, still has "sub3" even later on<br><br>Breakpoint 18, str_append_c (chr=<optimized out>, str=0x5555556930d0)<br>at str.h:44<br>44 buffer_append_c(str, chr);<br>(gdb) p (char*)(str->data)<br>$742 = 0x555555693110 "1ub3"<br><br>^^ reading left to right one char at a time "over the old value",<br>which didn't update the data.<br><br>So it seems in json_parse_number the ordering of<br>a) str_truncate(parser->value, 0);<br>b) the parsing itself<br>is messed up by optimization.<br><br>We already know from the above that reducing just this function to -O1 or less<br>avoids the issue. But what is it really - I don't know?<br><br>Maybe you have a better idea what is going on, the issue should be<br>reproducible when building<br>dovecot with the toolchain present on the latest Ubuntu being 21.04<br>(Hirsute) right now.<br><br>--<br>Christian Ehrhardt<br>Staff Engineer, Ubuntu Server<br>Canonical Ltd<br><br><br>------------------------------<br><br>Message: 3<br>Date: Tue, 30 Mar 2021 18:55:44 +0300 (EEST)<br>From: Aki Tuomi <aki.tuomi@open-xchange.com><br>To: Christian Ehrhardt <christian.ehrhardt@canonical.com>,<br>      dovecot@dovecot.org<br>Subject: Re: json_parse_number broken by compiler optimization<br>Message-ID:<br>      <1219230463.3728.1617119744636@appsuite-dev-gw1.open-xchange.com><br>Content-Type: text/plain; charset=UTF-8<br><br><br>> On 30/03/2021 18:53 Christian Ehrhardt <christian.ehrhardt@canonical.com> wrote:<br>> <br>>  <br>> Hi,<br>> the recent Ubuntu (re)builds uncovered an issue with dovecot 1:2.3.13+dfsg1-1<br>> build log: https://launchpadlibrarian.net/529849650/buildlog_ubuntu-hirsute-amd64.dovecot_1%3A2.3.13+dfsg1-1build1_BUILDING.txt.gz<br>> A coworker tried 2.3.14 but got the same result.<br>> <br>> What fails is the json_parser build time test like:<br>>   test-json-parser.c:161: Assert(#25) failed:<br>> null_strcmp(json_output[pos].value, value) == 0<br>> <br>> I was looking into that a bit more and what I found is that it is<br>> dependent on the new toolchain<br>> of gcc 10.2.0-1.<br>> <br>> Not all calls to json_parse_* fail, e.g. the first one looks all good and passes<br>> I was iterating the tests using a report function defined like<br>> <br>> (gdb) define repcon<br>> >c<br>> >p pos<br>> >p json_output[pos].type<br>> >p type<br>> >p json_output[pos].value<br>> >p value<br>> >call null_strcmp(json_output[pos].value, value)<br>> >end<br>> <br>> The first one to be bad was:<br>> Breakpoint 2, test_json_parser_success (full_size=<optimized out>) at<br>> test-json-parser.c:161<br>> 161 test_assert_idx(null_strcmp(json_output[pos].value, value) == 0, pos);<br>> $84 = 25<br>> $85 = JSON_TYPE_NUMBER<br>> $86 = JSON_TYPE_NUMBER<br>> $87 = 0x555555633b25 "-12.456"<br>> $88 = 0x555555693110 ""<br>> $89 = 45<br>> <br>> Earlier and later parsing was happy, for example<br>> <br>> Breakpoint 2, test_json_parser_success (full_size=<optimized out>) at<br>> test-json-parser.c:161<br>> 161 test_assert_idx(null_strcmp(json_output[pos].value, value) == 0, pos);<br>> $90 = 27<br>> $91 = JSON_TYPE_NUMBER<br>> $92 = JSON_TYPE_NUMBER<br>> $93 = 0x555555633b32 "12.456e9"<br>> $94 = 0x555555693110 "12.456e9"<br>> $95 = 0<br>> (gdb)<br>> <br>> <br>> We have two things we compare here.<br>> 1. json_output[] which is a static define and for this value is<br>>    67 ????{ JSON_TYPE_NUMBER, "-12.456" },<br>> 2. the return value that json_parse_next returns.<br>>    25 ????"  \"sub2\":-12.456,\n"<br>>   148 ????????????????ret = json_parse_next(parser, &type, &value);<br>> <br>> I tried a non negative number and got success which is suspicious<br>> <br>> Breakpoint 5, test_json_parser_success (full_size=<optimized out>) at<br>> test-json-parser.c:164<br>> 164 test_assert_idx(null_strcmp(json_output[pos].value, value) == 0, pos);<br>> $122 = 25<br>> $123 = JSON_TYPE_NUMBER<br>> $124 = JSON_TYPE_NUMBER<br>> $125 = 0x555555633b2c "12.456"<br>> $126 = 0x555555693110 "12.456"<br>> $127 = 0<br>> (gdb)<br>> <br>> <br>> Also the return value otherwise LGTM, it is recognized as a number:<br>> 540 } else if ((ret = json_parse_number(parser, value_r)) >= 0) {<br>> (gdb) n<br>> 541 *type_r = JSON_TYPE_NUMBER;<br>> <br>> So parsing worked one might think, but the value was not set.<br>> <br>> (gdb) p *value_r<br>> $833 = 0x555555693110 ""<br>> <br>> It turns out json_parse_number is too optimized.<br>> Too optimized for debugging further into json_parse_number.<br>> But also optimization is causing the issue.<br>> With -O0 or -O1 it works fine, even putting the lower optimization<br>> level just around json_parse_number it is enough to avoid the issue.<br>> <br>> <br>> Not a fix but "avoidance" for now:<br>> <br>> --- a/src/lib/json-parser.c<br>> +++ b/src/lib/json-parser.c<br>> @@ -386,6 +386,8 @@ static int json_parse_int(struct json_pa<br>>   return 1;<br>>  }<br>> <br>> +#pragma GCC push_options<br>> +#pragma GCC optimize ("-O0")<br>>  static int json_parse_number(struct json_parser *parser, const char **value_r)<br>>  {<br>>   int ret;<br>> @@ -415,6 +417,7 @@ static int json_parse_number(struct json<br>>   *value_r = str_c(parser->value);<br>>   return 1;<br>>  }<br>> +#pragma GCC pop_options<br>> <br>>  static int json_parse_atom(struct json_parser *parser, const char *atom)<br>>  {<br>> <br>> <br>> I was trying to see what happened and tracked each str_append_c<br>> that happened inside json_parse_number.<br>> A breakpoint on str_append_c and backtraces showed that we clearly do the<br>> "right" parsing. From the backtraces I've seen it does (just from positions):<br>> <br>> For example<br>> (gdb) bt<br>> #0  str_append_c (chr=<optimized out>, str=0x5555556930d0) at str.h:44<br>> #1  json_parse_digits (parser=<optimized out>) at json-parser.c:366<br>> => that is a digit<br>> <br>> It does "- digit digit dot digit digit digit"<br>> <br>> This perfectly matches the input value, but still the result stays empty:<br>> (gdb) p (char*)(str->data)<br>> $738 = 0x555555693110 ""<br>> <br>> In comparison - when parsing the latter 12.456e9 which works I see two<br>> odd things:<br>> 1. the value isn't cleared despite<br>>     str_truncate(parser->value, 0);<br>>    at the beginning of json_parse_number<br>> 2. the value (this time) is read exactly as I assumed<br>> <br>> Breakpoint 17, json_parse_number (value_r=0x7fffffffe1a0,<br>> parser=0x555555692ee0) at json-parser.c:394<br>> 394 str_truncate(parser->value, 0);<br>> Breakpoint 18, str_append_c (chr=<optimized out>, str=0x5555556930d0)<br>> at str.h:44<br>> 44 buffer_append_c(str, chr);<br>> (gdb) p (char*)(str->data)<br>> $741 = 0x555555693110 "sub3"<br>> <br>> ^^ not cleared, still has "sub3" even later on<br>> <br>> Breakpoint 18, str_append_c (chr=<optimized out>, str=0x5555556930d0)<br>> at str.h:44<br>> 44 buffer_append_c(str, chr);<br>> (gdb) p (char*)(str->data)<br>> $742 = 0x555555693110 "1ub3"<br>> <br>> ^^ reading left to right one char at a time "over the old value",<br>> which didn't update the data.<br>> <br>> So it seems in json_parse_number the ordering of<br>> a) str_truncate(parser->value, 0);<br>> b) the parsing itself<br>> is messed up by optimization.<br>> <br>> We already know from the above that reducing just this function to -O1 or less<br>> avoids the issue. But what is it really - I don't know?<br>> <br>> Maybe you have a better idea what is going on, the issue should be<br>> reproducible when building<br>> dovecot with the toolchain present on the latest Ubuntu being 21.04<br>> (Hirsute) right now.<br>> <br>> --<br>> Christian Ehrhardt<br>> Staff Engineer, Ubuntu Server<br>> Canonical Ltd<br><br>Thanks!<br><br>We'll look into this.<br><br>Aki<br><br><br>------------------------------<br><br>Subject: Digest Footer<br><br>_______________________________________________<br>dovecot mailing list<br>dovecot@dovecot.org<br>https://dovecot.org/mailman/listinfo/dovecot<br><br>------------------------------<br><br>End of dovecot Digest, Vol 215, Issue 77<br>****************************************<br></div>