Coverage Report

Created: 2023-03-26 07:33

/src/libunistring/lib/uniconv/u8-conv-from-enc.c
Line
Count
Source (jump to first uncovered line)
1
/* Conversion to UTF-8 from legacy encodings.
2
   Copyright (C) 2002, 2006-2007, 2009-2022 Free Software Foundation, Inc.
3
4
   This file is free software: you can redistribute it and/or modify
5
   it under the terms of the GNU Lesser General Public License as
6
   published by the Free Software Foundation; either version 2.1 of the
7
   License, or (at your option) any later version.
8
9
   This file 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
12
   GNU Lesser General Public License for more details.
13
14
   You should have received a copy of the GNU Lesser General Public License
15
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
16
17
/* Written by Bruno Haible <bruno@clisp.org>.  */
18
19
#include <config.h>
20
21
/* Specification.  */
22
#include "uniconv.h"
23
24
#include <errno.h>
25
#include <stdlib.h>
26
#include <string.h>
27
28
#include "c-strcaseeq.h"
29
#include "striconveha.h"
30
#include "unistr.h"
31
32
uint8_t *
33
u8_conv_from_encoding (const char *fromcode,
34
                       enum iconv_ilseq_handler handler,
35
                       const char *src, size_t srclen,
36
                       size_t *offsets,
37
                       uint8_t *resultbuf, size_t *lengthp)
38
0
{
39
0
  if (STRCASEEQ (fromcode, "UTF-8", 'U','T','F','-','8',0,0,0,0))
40
0
    {
41
      /* Conversion from UTF-8 to UTF-8.  No need to go through iconv().  */
42
0
      uint8_t *result;
43
44
0
      if (u8_check ((const uint8_t *) src, srclen))
45
0
        {
46
0
          errno = EILSEQ;
47
0
          return NULL;
48
0
        }
49
50
0
      if (offsets != NULL)
51
0
        {
52
0
          size_t i;
53
54
0
          for (i = 0; i < srclen; )
55
0
            {
56
0
              int count = u8_mblen ((const uint8_t *) src + i, srclen - i);
57
              /* We can rely on count > 0 because of the previous u8_check.  */
58
0
              if (count <= 0)
59
0
                abort ();
60
0
              offsets[i] = i;
61
0
              i++;
62
0
              while (--count > 0)
63
0
                offsets[i++] = (size_t)(-1);
64
0
            }
65
0
        }
66
67
      /* Memory allocation.  */
68
0
      if (resultbuf != NULL && *lengthp >= srclen)
69
0
        result = resultbuf;
70
0
      else
71
0
        {
72
0
          result = (uint8_t *) malloc (srclen > 0 ? srclen : 1);
73
0
          if (result == NULL)
74
0
            {
75
0
              errno = ENOMEM;
76
0
              return NULL;
77
0
            }
78
0
        }
79
80
0
      if (srclen > 0)
81
0
        memcpy ((char *) result, src, srclen);
82
0
      *lengthp = srclen;
83
0
      return result;
84
0
    }
85
0
  else
86
0
    {
87
0
      char *result = (char *) resultbuf;
88
0
      size_t length = *lengthp;
89
90
0
      if (mem_iconveha (src, srclen, fromcode, "UTF-8", true, handler,
91
0
                        offsets, &result, &length) < 0)
92
0
        return NULL;
93
94
0
      if (result == NULL) /* when (resultbuf == NULL && length == 0)  */
95
0
        {
96
0
          result = (char *) malloc (1);
97
0
          if (result == NULL)
98
0
            {
99
0
              errno = ENOMEM;
100
0
              return NULL;
101
0
            }
102
0
        }
103
0
      *lengthp = length;
104
0
      return (uint8_t *) result;
105
0
    }
106
0
}