Coverage Report

Created: 2023-03-26 07:33

/src/wget/lib/c-strcasestr.c
Line
Count
Source (jump to first uncovered line)
1
/* c-strcasestr.c -- case insensitive substring search in C locale
2
   Copyright (C) 2005-2023 Free Software Foundation, Inc.
3
   Written by Bruno Haible <bruno@clisp.org>, 2005.
4
5
   This file is free software: you can redistribute it and/or modify
6
   it under the terms of the GNU Lesser General Public License as
7
   published by the Free Software Foundation; either version 2.1 of the
8
   License, or (at your option) any later version.
9
10
   This file is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
   GNU Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public License
16
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
17
18
#include <config.h>
19
20
/* Specification.  */
21
#include "c-strcasestr.h"
22
23
#include <string.h>
24
25
#include "c-ctype.h"
26
#include "c-strcase.h"
27
28
/* Two-Way algorithm.  */
29
#define RETURN_TYPE char *
30
#define AVAILABLE(h, h_l, j, n_l)                       \
31
0
  (!memchr ((h) + (h_l), '\0', (j) + (n_l) - (h_l))     \
32
0
   && ((h_l) = (j) + (n_l)))
33
0
#define CANON_ELEMENT c_tolower
34
#define CMP_FUNC(p1, p2, l)                             \
35
0
  c_strncasecmp ((const char *) (p1), (const char *) (p2), l)
36
#include "str-two-way.h"
37
38
/* Find the first occurrence of NEEDLE in HAYSTACK, using case-insensitive
39
   comparison from the C locale, regardless of the current locale.  */
40
char *
41
c_strcasestr (const char *haystack_start, const char *needle_start)
42
0
{
43
0
  const char *haystack = haystack_start;
44
0
  const char *needle = needle_start;
45
0
  size_t needle_len; /* Length of NEEDLE.  */
46
0
  size_t haystack_len; /* Known minimum length of HAYSTACK.  */
47
0
  bool ok = true; /* True if NEEDLE is prefix of HAYSTACK.  */
48
49
  /* Determine length of NEEDLE, and in the process, make sure
50
     HAYSTACK is at least as long (no point processing all of a long
51
     NEEDLE if HAYSTACK is too short).  */
52
0
  while (*haystack && *needle)
53
0
    ok &= (c_tolower ((unsigned char) *haystack++)
54
0
           == c_tolower ((unsigned char) *needle++));
55
0
  if (*needle)
56
0
    return NULL;
57
0
  if (ok)
58
0
    return (char *) haystack_start;
59
0
  needle_len = needle - needle_start;
60
0
  haystack = haystack_start + 1;
61
0
  haystack_len = needle_len - 1;
62
63
  /* Perform the search.  Abstract memory is considered to be an array
64
     of 'unsigned char' values, not an array of 'char' values.  See
65
     ISO C 99 section 6.2.6.1.  */
66
0
  if (needle_len < LONG_NEEDLE_THRESHOLD)
67
0
    return two_way_short_needle ((const unsigned char *) haystack,
68
0
                                 haystack_len,
69
0
                                 (const unsigned char *) needle_start,
70
0
                                 needle_len);
71
0
  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
72
0
                              (const unsigned char *) needle_start,
73
0
                              needle_len);
74
0
}
75
76
#undef LONG_NEEDLE_THRESHOLD