(root)/
glibc-2.38/
debug/
strncat_chk.c
       1  /* Copyright (C) 1991-2023 Free Software Foundation, Inc.
       2     This file is part of the GNU C Library.
       3  
       4     The GNU C Library is free software; you can redistribute it and/or
       5     modify it under the terms of the GNU Lesser General Public
       6     License as published by the Free Software Foundation; either
       7     version 2.1 of the License, or (at your option) any later version.
       8  
       9     The GNU C Library is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public
      15     License along with the GNU C Library; if not, see
      16     <https://www.gnu.org/licenses/>.  */
      17  
      18  #include <string.h>
      19  
      20  #include <memcopy.h>
      21  
      22  
      23  char *
      24  __strncat_chk (char *s1, const char *s2, size_t n, size_t s1len)
      25  {
      26    char c;
      27    char *s = s1;
      28  
      29    /* Find the end of S1.  */
      30    do
      31      {
      32        if (__glibc_unlikely (s1len-- == 0))
      33  	__chk_fail ();
      34        c = *s1++;
      35      }
      36    while (c != '\0');
      37  
      38    /* Make S1 point before next character, so we can increment
      39       it while memory is read (wins on pipelined cpus).  */
      40    ++s1len;
      41    s1 -= 2;
      42  
      43    if (n >= 4)
      44      {
      45        size_t n4 = n >> 2;
      46        do
      47  	{
      48  	  if (__glibc_unlikely (s1len-- == 0))
      49  	    __chk_fail ();
      50  	  c = *s2++;
      51  	  *++s1 = c;
      52  	  if (c == '\0')
      53  	    return s;
      54  	  if (__glibc_unlikely (s1len-- == 0))
      55  	    __chk_fail ();
      56  	  c = *s2++;
      57  	  *++s1 = c;
      58  	  if (c == '\0')
      59  	    return s;
      60  	  if (__glibc_unlikely (s1len-- == 0))
      61  	    __chk_fail ();
      62  	  c = *s2++;
      63  	  *++s1 = c;
      64  	  if (c == '\0')
      65  	    return s;
      66  	  if (__glibc_unlikely (s1len-- == 0))
      67  	    __chk_fail ();
      68  	  c = *s2++;
      69  	  *++s1 = c;
      70  	  if (c == '\0')
      71  	    return s;
      72  	} while (--n4 > 0);
      73        n &= 3;
      74      }
      75  
      76    while (n > 0)
      77      {
      78        if (__glibc_unlikely (s1len-- == 0))
      79  	__chk_fail ();
      80        c = *s2++;
      81        *++s1 = c;
      82        if (c == '\0')
      83  	return s;
      84        n--;
      85      }
      86  
      87    if (c != '\0')
      88      {
      89        if (__glibc_unlikely (s1len-- == 0))
      90  	__chk_fail ();
      91        *++s1 = '\0';
      92      }
      93  
      94    return s;
      95  }