Coverage Report

Created: 2025-11-16 06:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/util-linux/lib/encode.c
Line
Count
Source
1
/*
2
 * Based on code from libblkid,
3
 *
4
 * Copyright (C) 2008 Kay Sievers <kay.sievers@vrfy.org>
5
 * Copyright (C) 2009 Karel Zak <kzak@redhat.com>
6
 * Copyright (C) 2020 Pali Rohár <pali.rohar@gmail.com>
7
 *
8
 * This file may be redistributed under the terms of the
9
 * GNU Lesser General Public License.
10
 */
11
#include "c.h"
12
#include "encode.h"
13
14
size_t ul_encode_to_utf8(int enc, unsigned char *dest, size_t len,
15
      const unsigned char *src, size_t count)
16
1.59k
{
17
1.59k
  size_t i, j;
18
1.59k
  uint32_t c;
19
1.59k
  uint16_t c2;
20
21
42.7k
  for (j = i = 0; i < count; i++) {
22
41.7k
    if (enc == UL_ENCODE_UTF16LE) {
23
11.7k
      if (i+2 > count)
24
8
        break;
25
11.7k
      c = (src[i+1] << 8) | src[i];
26
11.7k
      i++;
27
29.9k
    } else if (enc == UL_ENCODE_UTF16BE) {
28
19.0k
      if (i+2 > count)
29
16
        break;
30
18.9k
      c = (src[i] << 8) | src[i+1];
31
18.9k
      i++;
32
18.9k
    } else if (enc == UL_ENCODE_LATIN1) {
33
10.9k
      c = src[i];
34
10.9k
    } else {
35
0
      return 0;
36
0
    }
37
41.7k
    if ((enc == UL_ENCODE_UTF16LE || enc == UL_ENCODE_UTF16BE) &&
38
30.7k
        c >= 0xD800 && c <= 0xDBFF && i+2 < count) {
39
3.30k
      if (enc == UL_ENCODE_UTF16LE)
40
2.03k
        c2 = (src[i+2] << 8) | src[i+1];
41
1.26k
      else
42
1.26k
        c2 = (src[i+1] << 8) | src[i+2];
43
3.30k
      if (c2 >= 0xDC00 && c2 <= 0xDFFF) {
44
742
        c = 0x10000 + ((c - 0xD800) << 10) + (c2 - 0xDC00);
45
742
        i += 2;
46
742
      }
47
3.30k
    }
48
41.7k
    if (c == 0) {
49
387
      dest[j] = '\0';
50
387
      break;
51
387
    }
52
53
41.3k
    if (c < 0x80) {
54
22.4k
      if (j+1 >= len)
55
121
        break;
56
22.2k
      dest[j++] = (uint8_t) c;
57
22.2k
    } else if (c < 0x800) {
58
1.42k
      if (j+2 >= len)
59
4
        break;
60
1.42k
      dest[j++] = (uint8_t) (0xc0 | (c >> 6));
61
1.42k
      dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
62
17.4k
    } else if (c < 0x10000) {
63
16.7k
      if (j+3 >= len)
64
38
        break;
65
16.7k
      dest[j++] = (uint8_t) (0xe0 | (c >> 12));
66
16.7k
      dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
67
16.7k
      dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
68
16.7k
    } else {
69
742
      if (j+4 >= len)
70
0
        break;
71
742
      dest[j++] = (uint8_t) (0xf0 | (c >> 18));
72
742
      dest[j++] = (uint8_t) (0x80 | ((c >> 12) & 0x3f));
73
742
      dest[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f));
74
742
      dest[j++] = (uint8_t) (0x80 | (c & 0x3f));
75
742
    }
76
41.3k
  }
77
1.59k
  dest[j] = '\0';
78
1.59k
  return j;
79
1.59k
}