Message ID | 20200625173302.490857-1-rzinsly@linux.ibm.com |
---|---|
State | Superseded |
Headers |
Return-Path: <libc-alpha-bounces@sourceware.org> X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 95C573870905; Thu, 25 Jun 2020 17:33:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 95C573870905 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1593106392; bh=nhjuOG7lsVtAj54qvOd/60hJkkGm3MCt6VhU+VmC6UI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:Cc:From; b=upafchKmq/7AQSArQsVPz7KSVkC4gxJ/mLRNRmvRXI78IfYcSJHQ59LOdM1NuNuZe W+yNnKZtgmmiU8grtqmLYRYxlFf3UsrdDnejn2d/gP0N6zpeqOkXtsVkLWEEP1Bk9q cUzOlT5ZzvwH7sxs9do83zVStywKOg7jlYXt8J3s= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id 17E783851C16 for <libc-alpha@sourceware.org>; Thu, 25 Jun 2020 17:33:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 17E783851C16 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 05PHWGSX087631; Thu, 25 Jun 2020 13:33:09 -0400 Received: from ppma01wdc.us.ibm.com (fd.55.37a9.ip4.static.sl-reverse.com [169.55.85.253]) by mx0b-001b2d01.pphosted.com with ESMTP id 31uwyg7rpr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 25 Jun 2020 13:33:09 -0400 Received: from pps.filterd (ppma01wdc.us.ibm.com [127.0.0.1]) by ppma01wdc.us.ibm.com (8.16.0.42/8.16.0.42) with SMTP id 05PHTnE5019698; Thu, 25 Jun 2020 17:33:08 GMT Received: from b01cxnp22035.gho.pok.ibm.com (b01cxnp22035.gho.pok.ibm.com [9.57.198.25]) by ppma01wdc.us.ibm.com with ESMTP id 31uurtdtf7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 25 Jun 2020 17:33:08 +0000 Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp22035.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 05PHX8e153674420 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 25 Jun 2020 17:33:08 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 668EC112063; Thu, 25 Jun 2020 17:33:08 +0000 (GMT) Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C939A112061; Thu, 25 Jun 2020 17:33:07 +0000 (GMT) Received: from localhost (unknown [9.163.26.110]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP; Thu, 25 Jun 2020 17:33:07 +0000 (GMT) To: libc-alpha@sourceware.org Subject: [PATCH v5] string: Adds tests for test-strncasecmp and test-strncpy Date: Thu, 25 Jun 2020 14:33:02 -0300 Message-Id: <20200625173302.490857-1-rzinsly@linux.ibm.com> X-Mailer: git-send-email 2.26.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-TM-AS-GCONF: 00 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216, 18.0.687 definitions=2020-06-25_12:2020-06-25, 2020-06-25 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=1 impostorscore=0 mlxlogscore=705 mlxscore=0 priorityscore=1501 phishscore=0 malwarescore=0 cotscore=-2147483648 lowpriorityscore=0 bulkscore=0 clxscore=1015 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2004280000 definitions=main-2006250107 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list <libc-alpha.sourceware.org> List-Unsubscribe: <http://sourceware.org/mailman/options/libc-alpha>, <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe> List-Archive: <https://sourceware.org/pipermail/libc-alpha/> List-Post: <mailto:libc-alpha@sourceware.org> List-Help: <mailto:libc-alpha-request@sourceware.org?subject=help> List-Subscribe: <http://sourceware.org/mailman/listinfo/libc-alpha>, <mailto:libc-alpha-request@sourceware.org?subject=subscribe> From: Raphael Moreira Zinsly via Libc-alpha <libc-alpha@sourceware.org> Reply-To: Raphael Moreira Zinsly <rzinsly@linux.ibm.com> Cc: pc@us.ibm.com, Raphael Moreira Zinsly <rzinsly@linux.ibm.com> Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" <libc-alpha-bounces@sourceware.org> |
Series |
[v5] string: Adds tests for test-strncasecmp and test-strncpy
|
|
Commit Message
Raphael M Zinsly
June 25, 2020, 5:33 p.m. UTC
Changes since v4: - Changed do_page_tests() to test every string offset in both inputs using usual register sizes instead of relying on dcache following Adhemerval's suggestions. --- >8 --- Adds tests to check if strings placed at page bondaries are handled correctly by strncasecmp and strncpy similar to tests for strncmp and strnlen. --- string/test-strncasecmp.c | 44 +++++++++++++++++++++++++++++++++++++++ string/test-strncpy.c | 32 ++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+)
Comments
Hi Raphael, Following is my limited review, I may be misunderstanding something crucial about the tests, so take my review with a grain of salt. I understand that right now the test should pass, right? Is there any patch to strncasecmp or strncpy to make it buggy to trigger the test, so it catch the intended failure state it is checking? For my education, the problem with the page boundaries can happen at the beginning of the string or only at the end? > diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c > index 6a9c27beae..628135b962 100644 > --- a/string/test-strncasecmp.c > +++ b/string/test-strncasecmp.c > @@ -137,6 +137,49 @@ do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, > do_one_test (impl, s1, s2, n, exp_result); > } > > +static void > +do_page_tests (void) > +{ > + char *s1, *s2; > + int exp_result; > + /* Assumes up to 512-bit wide read/stores. */ > + const size_t maxoffset = 64; > + > + s1 = (char *) buf1 + (BUF1PAGES) * page_size - maxoffset; > + memset (s1, 'a', maxoffset - 1); > + s1[maxoffset - 1] = '\0'; > + > + s2 = (char *) buf2 + page_size - maxoffset; > + memset (s2, 'a', maxoffset - 1); > + s2[maxoffset - 1] = '\0'; > + This is just a cosmetic suggestion: you can declare s* and set them like do_random_test (But I am not sure if this is the standard or the exception). > diff --git a/string/test-strncpy.c b/string/test-strncpy.c > index c978753ad8..05c56e06a5 100644 > --- a/string/test-strncpy.c > +++ b/string/test-strncpy.c > @@ -155,6 +155,37 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) > do_one_test (impl, s2, s1, len, n); > } > > +static void > +do_page_tests (void) > +{ > + CHAR *s1, *s2; > + /* Assumes up to 512-bit wide read/stores. */ > + const size_t last_offset = 64; > + > + s2 = (CHAR *) buf2; > + s1 = (CHAR *) buf1; I believe s* should be at the end of buf*, the same as in test-strncasecmp.c? Cosmetics suggestion: Same as in test-strncasecmp.c. > + MEMSET (s1, '\1', last_offset); > + s1[last_offset] = '\0'; Not sure if relevant, but in test-strncasecmp.c, the size is 63 + '\n', here it is 64 + '\0'. But My math may be off, so sorry in advance. > + > + /* Both strings are bounded to a page with write/read access and the next > + page is protected with PROT_NONE (meaning that any access outside of the > + page regions will trigger an invalid memory access). > + > + The loop copies the string s1 for all possible offset up to last_offset > + for both inputs with a size larger than the string (so memory access > + outside the expected memory regions might trigger invalid access). */ > + > + for (size_t off1 = 0; off1 < last_offset; off1++) > + { > + for (size_t off2 = 0; off2 < last_offset; off2++) > + { > + FOR_EACH_IMPL (impl, 0) > + do_one_test (impl, (CHAR *) (s2 + off2), (CHAR *) (s1 + off1), > + last_offset - off1, last_offset + 1); Should s2 be cleanup before each test? I am thinking that the copy my fail but do_one_test compare the result as copied because the leftover from the previous copy. Cosmetic suggestion: Are the castings needed here as s* seems to be the right type already. I didn't test it without it though, so I am genuinely asking. o/ Raoni Fassina Firmino
Quoting Raphael Moreira Zinsly via Libc-alpha (2020-06-25 14:33:02) > Changes since v4: > - Changed do_page_tests() to test every string offset in both inputs > using usual register sizes instead of relying on dcache following > Adhemerval's suggestions. > > --- >8 --- > > Adds tests to check if strings placed at page bondaries are > handled correctly by strncasecmp and strncpy similar to tests > for strncmp and strnlen. > --- > string/test-strncasecmp.c | 44 +++++++++++++++++++++++++++++++++++++++ > string/test-strncpy.c | 32 ++++++++++++++++++++++++++++ > 2 files changed, 76 insertions(+) > > diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c > index 6a9c27beae..628135b962 100644 > --- a/string/test-strncasecmp.c > +++ b/string/test-strncasecmp.c > @@ -137,6 +137,49 @@ do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, > do_one_test (impl, s1, s2, n, exp_result); > } > > +static void > +do_page_tests (void) > +{ > + char *s1, *s2; > + int exp_result; > + /* Assumes up to 512-bit wide read/stores. */ > + const size_t maxoffset = 64; > + > + s1 = (char *) buf1 + (BUF1PAGES) * page_size - maxoffset; > + memset (s1, 'a', maxoffset - 1); > + s1[maxoffset - 1] = '\0'; > + > + s2 = (char *) buf2 + page_size - maxoffset; > + memset (s2, 'a', maxoffset - 1); > + s2[maxoffset - 1] = '\0'; > + OK. > + /* At this point s1 and s2 points to distinct memory regions containing > + "aa..." with size of 63 plus '\0'. Also, both strings are bounded to a > + page with write/read access and the next page is protected with PROT_NONE > + (meaning that any access outside of the page regions will trigger an > + invalid memory access). > + > + The loop checks for all possible offset up to maxoffset for both > + inputs with a size larger than the string (so memory access outside > + the expected memory regions might trigger invalid access). */ > + OK. > + for (size_t off1 = 0; off1 < maxoffset; off1++) > + { > + for (size_t off2 = 0; off2 < maxoffset; off2++) > + { > + exp_result = off1 == off2 > + ? 0 > + : off1 < off2 > + ? 'a' > + : -'a'; > + > + FOR_EACH_IMPL (impl, 0) > + check_result (impl, s1 + off1, s2 + off2, maxoffset + 1, > + exp_result); Should't this be maxoffset - Max(off1,off2) > + } > + } > +} > + > static void > do_random_tests (void) > { > @@ -334,6 +377,7 @@ test_locale (const char *locale) > } > > do_random_tests (); > + do_page_tests (); > } > OK. > int > diff --git a/string/test-strncpy.c b/string/test-strncpy.c > index c978753ad8..05c56e06a5 100644 > --- a/string/test-strncpy.c > +++ b/string/test-strncpy.c > @@ -155,6 +155,37 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) > do_one_test (impl, s2, s1, len, n); > } > > +static void > +do_page_tests (void) > +{ > + CHAR *s1, *s2; > + /* Assumes up to 512-bit wide read/stores. */ > + const size_t last_offset = 64; > + Here you had a calculation for the last offset and now it's just 64. This is not setting s1 to be the last offset for the buf1 last page. Is it correct? AFAICS it should be the same calculation from the above test (BUF1PAGES*page_sizes - 64) > + s2 = (CHAR *) buf2; > + s1 = (CHAR *) buf1; > + MEMSET (s1, '\1', last_offset); > + s1[last_offset] = '\0'; If I'm correct above this should be: s1 = (CHAR *)buf1 + last_offset; MEMSET (s1, '\1', 63); s1[64] = '\0'; > + OK. > + /* Both strings are bounded to a page with write/read access and the next > + page is protected with PROT_NONE (meaning that any access outside of the > + page regions will trigger an invalid memory access). > + > + The loop copies the string s1 for all possible offset up to last_offset > + for both inputs with a size larger than the string (so memory access > + outside the expected memory regions might trigger invalid access). */ > + OK. > + for (size_t off1 = 0; off1 < last_offset; off1++) > + { > + for (size_t off2 = 0; off2 < last_offset; off2++) > + { > + FOR_EACH_IMPL (impl, 0) > + do_one_test (impl, (CHAR *) (s2 + off2), (CHAR *) (s1 + off1), > + last_offset - off1, last_offset + 1); > + } > + } > +} > + If I was correct above last_offset must be changed here to 64. > static void > do_random_tests (void) > { > @@ -317,6 +348,7 @@ test_main (void) > } > > do_random_tests (); > + do_page_tests (); > return ret; > } > OK. > -- > 2.26.2 >
On 01/07/2020 18:47, Raoni Fassina Firmino wrote: > Hi Raphael, > > > Following is my limited review, I may be misunderstanding something > crucial about the tests, so take my review with a grain of salt. > > I understand that right now the test should pass, right? Is there any > patch to strncasecmp or strncpy to make it buggy to trigger the test, so > it catch the intended failure state it is checking? > It is passing, the motivation is to improve the coverage of these tests and avoid errors on future optimizations. > For my education, the problem with the page boundaries can happen at the > beginning of the string or only at the end? > Only at the end. Unless a user force it I can't see how it would cross the page boundary at the beginning of the string, AFAICS this is not being handle by these functions and it shouldn't. >> diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c >> index 6a9c27beae..628135b962 100644 >> --- a/string/test-strncasecmp.c >> +++ b/string/test-strncasecmp.c >> @@ -137,6 +137,49 @@ do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, >> do_one_test (impl, s1, s2, n, exp_result); >> } >> >> +static void >> +do_page_tests (void) >> +{ >> + char *s1, *s2; >> + int exp_result; >> + /* Assumes up to 512-bit wide read/stores. */ >> + const size_t maxoffset = 64; >> + >> + s1 = (char *) buf1 + (BUF1PAGES) * page_size - maxoffset; >> + memset (s1, 'a', maxoffset - 1); >> + s1[maxoffset - 1] = '\0'; >> + >> + s2 = (char *) buf2 + page_size - maxoffset; >> + memset (s2, 'a', maxoffset - 1); >> + s2[maxoffset - 1] = '\0'; >> + > > This is just a cosmetic suggestion: you can declare s* and set them like > do_random_test (But I am not sure if this is the standard or the > exception). > It doesn't seem to have a standard between the string tests. > >> diff --git a/string/test-strncpy.c b/string/test-strncpy.c >> index c978753ad8..05c56e06a5 100644 >> --- a/string/test-strncpy.c >> +++ b/string/test-strncpy.c >> @@ -155,6 +155,37 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) >> do_one_test (impl, s2, s1, len, n); >> } >> >> +static void >> +do_page_tests (void) >> +{ >> + CHAR *s1, *s2; >> + /* Assumes up to 512-bit wide read/stores. */ >> + const size_t last_offset = 64; >> + >> + s2 = (CHAR *) buf2; >> + s1 = (CHAR *) buf1; > > I believe s* should be at the end of buf*, the same as in > test-strncasecmp.c? > I was reusing code from v4 e left this unchanged, you are right it should be as in the strncasecmp test, however I got a segfault testing the change, I'm investigating to see if this is a bug in my test or in strncpy. > Cosmetics suggestion: Same as in test-strncasecmp.c. > > >> + MEMSET (s1, '\1', last_offset); >> + s1[last_offset] = '\0'; > > Not sure if relevant, but in test-strncasecmp.c, the size is 63 + '\n', > here it is 64 + '\0'. But My math may be off, so sorry in advance. > Correct, I was using last_offset 63 and decided to change it in the end and mistakenly left this part unchanged. > >> + >> + /* Both strings are bounded to a page with write/read access and the next >> + page is protected with PROT_NONE (meaning that any access outside of the >> + page regions will trigger an invalid memory access). >> + >> + The loop copies the string s1 for all possible offset up to last_offset >> + for both inputs with a size larger than the string (so memory access >> + outside the expected memory regions might trigger invalid access). */ >> + >> + for (size_t off1 = 0; off1 < last_offset; off1++) >> + { >> + for (size_t off2 = 0; off2 < last_offset; off2++) >> + { >> + FOR_EACH_IMPL (impl, 0) >> + do_one_test (impl, (CHAR *) (s2 + off2), (CHAR *) (s1 + off1), >> + last_offset - off1, last_offset + 1); > > Should s2 be cleanup before each test? I am thinking that the copy my > fail but do_one_test compare the result as copied because the leftover > from the previous copy. > If it gets an invalid memory access it will fail even with the leftover. > Cosmetic suggestion: Are the castings needed here as s* seems to be the > right type already. I didn't test it without it though, so I am > genuinely asking. > I had to used it for wcsncpy at the beggining, but I tested and it works fine now without the cast. > > o/ > Raoni Fassina Firmino > Thanks,
On 02/07/2020 10:35, Lucas A. M. Magalhaes wrote: > Quoting Raphael Moreira Zinsly via Libc-alpha (2020-06-25 14:33:02) >> Changes since v4: >> - Changed do_page_tests() to test every string offset in both inputs >> using usual register sizes instead of relying on dcache following >> Adhemerval's suggestions. >> >> --- >8 --- >> >> Adds tests to check if strings placed at page bondaries are >> handled correctly by strncasecmp and strncpy similar to tests >> for strncmp and strnlen. >> --- >> string/test-strncasecmp.c | 44 +++++++++++++++++++++++++++++++++++++++ >> string/test-strncpy.c | 32 ++++++++++++++++++++++++++++ >> 2 files changed, 76 insertions(+) >> >> diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c >> index 6a9c27beae..628135b962 100644 >> --- a/string/test-strncasecmp.c >> +++ b/string/test-strncasecmp.c >> @@ -137,6 +137,49 @@ do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, >> do_one_test (impl, s1, s2, n, exp_result); >> } >> >> +static void >> +do_page_tests (void) >> +{ >> + char *s1, *s2; >> + int exp_result; >> + /* Assumes up to 512-bit wide read/stores. */ >> + const size_t maxoffset = 64; >> + >> + s1 = (char *) buf1 + (BUF1PAGES) * page_size - maxoffset; >> + memset (s1, 'a', maxoffset - 1); >> + s1[maxoffset - 1] = '\0'; >> + >> + s2 = (char *) buf2 + page_size - maxoffset; >> + memset (s2, 'a', maxoffset - 1); >> + s2[maxoffset - 1] = '\0'; >> + > > OK. > >> + /* At this point s1 and s2 points to distinct memory regions containing >> + "aa..." with size of 63 plus '\0'. Also, both strings are bounded to a >> + page with write/read access and the next page is protected with PROT_NONE >> + (meaning that any access outside of the page regions will trigger an >> + invalid memory access). >> + >> + The loop checks for all possible offset up to maxoffset for both >> + inputs with a size larger than the string (so memory access outside >> + the expected memory regions might trigger invalid access). */ >> + > > OK. > >> + for (size_t off1 = 0; off1 < maxoffset; off1++) >> + { >> + for (size_t off2 = 0; off2 < maxoffset; off2++) >> + { >> + exp_result = off1 == off2 >> + ? 0 >> + : off1 < off2 >> + ? 'a' >> + : -'a'; >> + >> + FOR_EACH_IMPL (impl, 0) >> + check_result (impl, s1 + off1, s2 + off2, maxoffset + 1, >> + exp_result); > > Should't this be maxoffset - Max(off1,off2) > Why? The idea is to test with a size larger than the string, this would be shorter. >> + } >> + } >> +} >> + >> static void >> do_random_tests (void) >> { >> @@ -334,6 +377,7 @@ test_locale (const char *locale) >> } >> >> do_random_tests (); >> + do_page_tests (); >> } >> > > OK. > >> int >> diff --git a/string/test-strncpy.c b/string/test-strncpy.c >> index c978753ad8..05c56e06a5 100644 >> --- a/string/test-strncpy.c >> +++ b/string/test-strncpy.c >> @@ -155,6 +155,37 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) >> do_one_test (impl, s2, s1, len, n); >> } >> >> +static void >> +do_page_tests (void) >> +{ >> + CHAR *s1, *s2; >> + /* Assumes up to 512-bit wide read/stores. */ >> + const size_t last_offset = 64; >> + > > Here you had a calculation for the last offset and now it's just 64. > This is not setting s1 to be the last offset for the buf1 last page. Is > it correct? AFAICS it should be the same calculation from the above > test (BUF1PAGES*page_sizes - 64) > Yes, as I replied to Raoni, this should be as the other test. >> + s2 = (CHAR *) buf2; >> + s1 = (CHAR *) buf1; >> + MEMSET (s1, '\1', last_offset); >> + s1[last_offset] = '\0'; > > If I'm correct above this should be: > s1 = (CHAR *)buf1 + last_offset; > MEMSET (s1, '\1', 63); > s1[64] = '\0'; > >> + > > OK. > >> + /* Both strings are bounded to a page with write/read access and the next >> + page is protected with PROT_NONE (meaning that any access outside of the >> + page regions will trigger an invalid memory access). >> + >> + The loop copies the string s1 for all possible offset up to last_offset >> + for both inputs with a size larger than the string (so memory access >> + outside the expected memory regions might trigger invalid access). */ >> + > > OK. > >> + for (size_t off1 = 0; off1 < last_offset; off1++) >> + { >> + for (size_t off2 = 0; off2 < last_offset; off2++) >> + { >> + FOR_EACH_IMPL (impl, 0) >> + do_one_test (impl, (CHAR *) (s2 + off2), (CHAR *) (s1 + off1), >> + last_offset - off1, last_offset + 1); >> + } >> + } >> +} >> + > > If I was correct above last_offset must be changed here to 64. > >> static void >> do_random_tests (void) >> { >> @@ -317,6 +348,7 @@ test_main (void) >> } >> >> do_random_tests (); >> + do_page_tests (); >> return ret; >> } >> > > OK. > >> -- >> 2.26.2 >> Thank you,
diff --git a/string/test-strncasecmp.c b/string/test-strncasecmp.c index 6a9c27beae..628135b962 100644 --- a/string/test-strncasecmp.c +++ b/string/test-strncasecmp.c @@ -137,6 +137,49 @@ do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char, do_one_test (impl, s1, s2, n, exp_result); } +static void +do_page_tests (void) +{ + char *s1, *s2; + int exp_result; + /* Assumes up to 512-bit wide read/stores. */ + const size_t maxoffset = 64; + + s1 = (char *) buf1 + (BUF1PAGES) * page_size - maxoffset; + memset (s1, 'a', maxoffset - 1); + s1[maxoffset - 1] = '\0'; + + s2 = (char *) buf2 + page_size - maxoffset; + memset (s2, 'a', maxoffset - 1); + s2[maxoffset - 1] = '\0'; + + /* At this point s1 and s2 points to distinct memory regions containing + "aa..." with size of 63 plus '\0'. Also, both strings are bounded to a + page with write/read access and the next page is protected with PROT_NONE + (meaning that any access outside of the page regions will trigger an + invalid memory access). + + The loop checks for all possible offset up to maxoffset for both + inputs with a size larger than the string (so memory access outside + the expected memory regions might trigger invalid access). */ + + for (size_t off1 = 0; off1 < maxoffset; off1++) + { + for (size_t off2 = 0; off2 < maxoffset; off2++) + { + exp_result = off1 == off2 + ? 0 + : off1 < off2 + ? 'a' + : -'a'; + + FOR_EACH_IMPL (impl, 0) + check_result (impl, s1 + off1, s2 + off2, maxoffset + 1, + exp_result); + } + } +} + static void do_random_tests (void) { @@ -334,6 +377,7 @@ test_locale (const char *locale) } do_random_tests (); + do_page_tests (); } int diff --git a/string/test-strncpy.c b/string/test-strncpy.c index c978753ad8..05c56e06a5 100644 --- a/string/test-strncpy.c +++ b/string/test-strncpy.c @@ -155,6 +155,37 @@ do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char) do_one_test (impl, s2, s1, len, n); } +static void +do_page_tests (void) +{ + CHAR *s1, *s2; + /* Assumes up to 512-bit wide read/stores. */ + const size_t last_offset = 64; + + s2 = (CHAR *) buf2; + s1 = (CHAR *) buf1; + MEMSET (s1, '\1', last_offset); + s1[last_offset] = '\0'; + + /* Both strings are bounded to a page with write/read access and the next + page is protected with PROT_NONE (meaning that any access outside of the + page regions will trigger an invalid memory access). + + The loop copies the string s1 for all possible offset up to last_offset + for both inputs with a size larger than the string (so memory access + outside the expected memory regions might trigger invalid access). */ + + for (size_t off1 = 0; off1 < last_offset; off1++) + { + for (size_t off2 = 0; off2 < last_offset; off2++) + { + FOR_EACH_IMPL (impl, 0) + do_one_test (impl, (CHAR *) (s2 + off2), (CHAR *) (s1 + off1), + last_offset - off1, last_offset + 1); + } + } +} + static void do_random_tests (void) { @@ -317,6 +348,7 @@ test_main (void) } do_random_tests (); + do_page_tests (); return ret; }