Coverage Report

Created: 2024-02-25 07:20

/src/libfsfat/libuna/libuna_codepage_windows_1252.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Windows 1252 codepage (Western European/Latin 1) functions
3
 *
4
 * Copyright (C) 2008-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <types.h>
24
25
#include "libuna_codepage_windows_1252.h"
26
#include "libuna_libcerror.h"
27
#include "libuna_types.h"
28
29
/* Extended ASCII to Unicode character lookup table for the Windows 1252 codepage
30
 * Unknown are filled with the Unicode replacement character 0xfffd
31
 */
32
const uint16_t libuna_codepage_windows_1252_byte_stream_to_unicode_base_0x80[ 32 ] = {
33
  0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
34
  0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0x017d, 0xfffd,
35
  0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
36
  0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0x017e, 0x0178
37
};
38
39
/* Unicode to ASCII character lookup tables for the Windows 1252 codepage
40
 * Unknown are filled with the ASCII replacement character 0x1a
41
 */
42
const uint8_t libuna_codepage_windows_1252_unicode_to_byte_stream_base_0x2010[ 24 ] = {
43
  0x1a, 0x1a, 0x1a, 0x96, 0x97, 0x1a, 0x1a, 0x1a,
44
  0x91, 0x92, 0x82, 0x1a, 0x93, 0x94, 0x84, 0x1a,
45
  0x86, 0x87, 0x95, 0x1a, 0x1a, 0x1a, 0x85, 0x1a
46
};
47
48
/* Copies an Unicode character from a Windows 1252 encoded byte stream
49
 * Returns 1 if successful or -1 on error
50
 */
51
int libuna_codepage_windows_1252_copy_from_byte_stream(
52
     libuna_unicode_character_t *unicode_character,
53
     const uint8_t *byte_stream,
54
     size_t byte_stream_size,
55
     size_t *byte_stream_index,
56
     libcerror_error_t **error )
57
90.1k
{
58
90.1k
  static char *function                             = "libuna_codepage_windows_1252_copy_from_byte_stream";
59
90.1k
  libuna_unicode_character_t safe_unicode_character = 0xfffd;
60
90.1k
  size_t safe_byte_stream_index                     = 0;
61
90.1k
  uint8_t byte_stream_character                     = 0;
62
63
90.1k
  if( unicode_character == NULL )
64
0
  {
65
0
    libcerror_error_set(
66
0
     error,
67
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
68
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
69
0
     "%s: invalid Unicode character.",
70
0
     function );
71
72
0
    return( -1 );
73
0
  }
74
90.1k
  if( byte_stream == NULL )
75
0
  {
76
0
    libcerror_error_set(
77
0
     error,
78
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
79
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
80
0
     "%s: invalid byte stream.",
81
0
     function );
82
83
0
    return( -1 );
84
0
  }
85
90.1k
  if( byte_stream_size > (size_t) SSIZE_MAX )
86
0
  {
87
0
    libcerror_error_set(
88
0
     error,
89
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
90
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
91
0
     "%s: invalid byte stream size value exceeds maximum.",
92
0
     function );
93
94
0
    return( -1 );
95
0
  }
96
90.1k
  if( byte_stream_index == NULL )
97
0
  {
98
0
    libcerror_error_set(
99
0
     error,
100
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
101
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
102
0
     "%s: invalid byte stream index.",
103
0
     function );
104
105
0
    return( -1 );
106
0
  }
107
90.1k
  safe_byte_stream_index = *byte_stream_index;
108
109
90.1k
  if( safe_byte_stream_index >= byte_stream_size )
110
0
  {
111
0
    libcerror_error_set(
112
0
     error,
113
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
114
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
115
0
     "%s: byte stream too small.",
116
0
     function );
117
118
0
    return( -1 );
119
0
  }
120
90.1k
  byte_stream_character = byte_stream[ safe_byte_stream_index++ ];
121
122
90.1k
  if( ( byte_stream_character < 0x80 )
123
90.1k
   || ( byte_stream_character >= 0xa0 ) )
124
86.6k
  {
125
86.6k
    safe_unicode_character = byte_stream_character;
126
86.6k
  }
127
3.48k
  else
128
3.48k
  {
129
3.48k
    byte_stream_character -= 0x80;
130
131
3.48k
    safe_unicode_character = libuna_codepage_windows_1252_byte_stream_to_unicode_base_0x80[ byte_stream_character ];
132
3.48k
  }
133
90.1k
  *unicode_character = safe_unicode_character;
134
90.1k
  *byte_stream_index = safe_byte_stream_index;
135
136
90.1k
  return( 1 );
137
90.1k
}
138
139
/* Copies an Unicode character to a Windows 1252 encoded byte stream
140
 * Returns 1 if successful or -1 on error
141
 */
142
int libuna_codepage_windows_1252_copy_to_byte_stream(
143
     libuna_unicode_character_t unicode_character,
144
     uint8_t *byte_stream,
145
     size_t byte_stream_size,
146
     size_t *byte_stream_index,
147
     libcerror_error_t **error )
148
0
{
149
0
  static char *function         = "libuna_codepage_windows_1252_copy_to_byte_stream";
150
0
  size_t safe_byte_stream_index = 0;
151
0
  uint16_t byte_stream_value    = 0x001a;
152
153
0
  if( byte_stream == NULL )
154
0
  {
155
0
    libcerror_error_set(
156
0
     error,
157
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
158
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
159
0
     "%s: invalid byte stream.",
160
0
     function );
161
162
0
    return( -1 );
163
0
  }
164
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
165
0
  {
166
0
    libcerror_error_set(
167
0
     error,
168
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
169
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
170
0
     "%s: invalid byte stream size value exceeds maximum.",
171
0
     function );
172
173
0
    return( -1 );
174
0
  }
175
0
  if( byte_stream_index == NULL )
176
0
  {
177
0
    libcerror_error_set(
178
0
     error,
179
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
180
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
181
0
     "%s: invalid byte stream index.",
182
0
     function );
183
184
0
    return( -1 );
185
0
  }
186
0
  safe_byte_stream_index = *byte_stream_index;
187
188
0
  if( safe_byte_stream_index >= byte_stream_size )
189
0
  {
190
0
    libcerror_error_set(
191
0
     error,
192
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
193
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
194
0
     "%s: byte stream too small.",
195
0
     function );
196
197
0
    return( -1 );
198
0
  }
199
0
  if( unicode_character < 0x0080 )
200
0
  {
201
0
    byte_stream_value = (uint16_t) unicode_character;
202
0
  }
203
0
  else if( ( unicode_character >= 0x00a0 )
204
0
        && ( unicode_character < 0x0100 ) )
205
0
  {
206
0
    byte_stream_value = (uint16_t) unicode_character;
207
0
  }
208
0
  else if( ( unicode_character >= 0x2010 )
209
0
        && ( unicode_character < 0x2028 ) )
210
0
  {
211
0
    unicode_character -= 0x2010;
212
213
0
    byte_stream_value = libuna_codepage_windows_1252_unicode_to_byte_stream_base_0x2010[ unicode_character ];
214
0
  }
215
0
  else switch( unicode_character )
216
0
  {
217
0
    case 0x0152:
218
0
      byte_stream_value = 0x8c;
219
0
      break;
220
221
0
    case 0x0153:
222
0
      byte_stream_value = 0x9c;
223
0
      break;
224
225
0
    case 0x0160:
226
0
      byte_stream_value = 0x8a;
227
0
      break;
228
229
0
    case 0x0161:
230
0
      byte_stream_value = 0x9a;
231
0
      break;
232
233
0
    case 0x0178:
234
0
      byte_stream_value = 0x9f;
235
0
      break;
236
237
0
    case 0x017d:
238
0
      byte_stream_value = 0x8e;
239
0
      break;
240
241
0
    case 0x017e:
242
0
      byte_stream_value = 0x9e;
243
0
      break;
244
245
0
    case 0x0192:
246
0
      byte_stream_value = 0x83;
247
0
      break;
248
249
0
    case 0x02c6:
250
0
      byte_stream_value = 0x88;
251
0
      break;
252
253
0
    case 0x02dc:
254
0
      byte_stream_value = 0x98;
255
0
      break;
256
257
0
    case 0x2030:
258
0
      byte_stream_value = 0x89;
259
0
      break;
260
261
0
    case 0x2039:
262
0
      byte_stream_value = 0x8b;
263
0
      break;
264
265
0
    case 0x203a:
266
0
      byte_stream_value = 0x9b;
267
0
      break;
268
269
0
    case 0x20ac:
270
0
      byte_stream_value = 0x80;
271
0
      break;
272
273
0
    case 0x2122:
274
0
      byte_stream_value = 0x99;
275
0
      break;
276
277
0
    default:
278
0
      byte_stream_value = 0x1a;
279
0
      break;
280
0
  }
281
0
  byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( byte_stream_value & 0x00ff );
282
283
0
  *byte_stream_index = safe_byte_stream_index;
284
285
0
  return( 1 );
286
0
}
287