Coverage Report

Created: 2024-02-25 07:20

/src/libfvde/libuna/libuna_codepage_windows_1254.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Windows 1254 codepage (Turkish) 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_1254.h"
26
#include "libuna_libcerror.h"
27
#include "libuna_types.h"
28
29
/* Extended ASCII to Unicode character lookup tables for the Windows 1254 codepage
30
 * Unknown are filled with the Unicode replacement character 0xfffd
31
 */
32
const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0x80[ 32 ] = {
33
  0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021,
34
  0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd,
35
  0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014,
36
  0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178,
37
};
38
39
const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xd0[ 16 ] = {
40
  0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
41
  0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df,
42
};
43
44
const uint16_t libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xf0[ 16 ] = {
45
  0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
46
  0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff,
47
};
48
49
/* Unicode to ASCII character lookup tables for the Windows 1254 codepage
50
 * Unknown are filled with the ASCII replacement character 0x1a
51
 */
52
const uint8_t libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x00d0[ 48 ] = {
53
  0x1a, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
54
  0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x1a, 0x1a, 0xdf,
55
  0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
56
  0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
57
  0x1a, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
58
  0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x1a, 0x1a, 0xff,
59
};
60
61
const uint8_t libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x2010[ 24 ] = {
62
  0x1a, 0x1a, 0x1a, 0x96, 0x97, 0x1a, 0x1a, 0x1a,
63
  0x91, 0x92, 0x82, 0x1a, 0x93, 0x94, 0x84, 0x1a,
64
  0x86, 0x87, 0x95, 0x1a, 0x1a, 0x1a, 0x85, 0x1a,
65
};
66
67
/* Copies an Unicode character from a Windows 1254 encoded byte stream
68
 * Returns 1 if successful or -1 on error
69
 */
70
int libuna_codepage_windows_1254_copy_from_byte_stream(
71
     libuna_unicode_character_t *unicode_character,
72
     const uint8_t *byte_stream,
73
     size_t byte_stream_size,
74
     size_t *byte_stream_index,
75
     libcerror_error_t **error )
76
0
{
77
0
  static char *function                             = "libuna_codepage_windows_1254_copy_from_byte_stream";
78
0
  libuna_unicode_character_t safe_unicode_character = 0xfffd;
79
0
  size_t safe_byte_stream_index                     = 0;
80
0
  uint8_t byte_stream_character                     = 0;
81
82
0
  if( unicode_character == NULL )
83
0
  {
84
0
    libcerror_error_set(
85
0
     error,
86
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
87
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
88
0
     "%s: invalid Unicode character.",
89
0
     function );
90
91
0
    return( -1 );
92
0
  }
93
0
  if( byte_stream == NULL )
94
0
  {
95
0
    libcerror_error_set(
96
0
     error,
97
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
98
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
99
0
     "%s: invalid byte stream.",
100
0
     function );
101
102
0
    return( -1 );
103
0
  }
104
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
105
0
  {
106
0
    libcerror_error_set(
107
0
     error,
108
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
109
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
110
0
     "%s: invalid byte stream size value exceeds maximum.",
111
0
     function );
112
113
0
    return( -1 );
114
0
  }
115
0
  if( byte_stream_index == NULL )
116
0
  {
117
0
    libcerror_error_set(
118
0
     error,
119
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
120
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
121
0
     "%s: invalid byte stream index.",
122
0
     function );
123
124
0
    return( -1 );
125
0
  }
126
0
  safe_byte_stream_index = *byte_stream_index;
127
128
0
  if( safe_byte_stream_index >= byte_stream_size )
129
0
  {
130
0
    libcerror_error_set(
131
0
     error,
132
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
133
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
134
0
     "%s: byte stream too small.",
135
0
     function );
136
137
0
    return( -1 );
138
0
  }
139
0
  byte_stream_character = byte_stream[ safe_byte_stream_index++ ];
140
141
0
  if( byte_stream_character < 0x80 )
142
0
  {
143
0
    safe_unicode_character = byte_stream_character;
144
0
  }
145
0
  else if( byte_stream_character < 0xa0 )
146
0
  {
147
0
    byte_stream_character -= 0x80;
148
149
0
    safe_unicode_character = libuna_codepage_windows_1254_byte_stream_to_unicode_base_0x80[ byte_stream_character ];
150
0
  }
151
0
  else if( byte_stream_character < 0xd0 )
152
0
  {
153
0
    safe_unicode_character = byte_stream_character;
154
0
  }
155
0
  else if( byte_stream_character < 0xe0 )
156
0
  {
157
0
    byte_stream_character -= 0xd0;
158
159
0
    safe_unicode_character = libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xd0[ byte_stream_character ];
160
0
  }
161
0
  else if( byte_stream_character < 0xf0 )
162
0
  {
163
0
    safe_unicode_character = byte_stream_character;
164
0
  }
165
0
  else
166
0
  {
167
0
    byte_stream_character -= 0xf0;
168
169
0
    safe_unicode_character = libuna_codepage_windows_1254_byte_stream_to_unicode_base_0xf0[ byte_stream_character ];
170
0
  }
171
0
  *unicode_character = safe_unicode_character;
172
0
  *byte_stream_index = safe_byte_stream_index;
173
174
0
  return( 1 );
175
0
}
176
177
/* Copies an Unicode character to a Windows 1254 encoded byte stream
178
 * Returns 1 if successful or -1 on error
179
 */
180
int libuna_codepage_windows_1254_copy_to_byte_stream(
181
     libuna_unicode_character_t unicode_character,
182
     uint8_t *byte_stream,
183
     size_t byte_stream_size,
184
     size_t *byte_stream_index,
185
     libcerror_error_t **error )
186
0
{
187
0
  static char *function         = "libuna_codepage_windows_1254_copy_to_byte_stream";
188
0
  size_t safe_byte_stream_index = 0;
189
0
  uint16_t byte_stream_value    = 0x001a;
190
191
0
  if( byte_stream == NULL )
192
0
  {
193
0
    libcerror_error_set(
194
0
     error,
195
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
196
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
197
0
     "%s: invalid byte stream.",
198
0
     function );
199
200
0
    return( -1 );
201
0
  }
202
0
  if( byte_stream_size > (size_t) SSIZE_MAX )
203
0
  {
204
0
    libcerror_error_set(
205
0
     error,
206
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
207
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
208
0
     "%s: invalid byte stream size value exceeds maximum.",
209
0
     function );
210
211
0
    return( -1 );
212
0
  }
213
0
  if( byte_stream_index == NULL )
214
0
  {
215
0
    libcerror_error_set(
216
0
     error,
217
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
218
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
219
0
     "%s: invalid byte stream index.",
220
0
     function );
221
222
0
    return( -1 );
223
0
  }
224
0
  safe_byte_stream_index = *byte_stream_index;
225
226
0
  if( safe_byte_stream_index >= byte_stream_size )
227
0
  {
228
0
    libcerror_error_set(
229
0
     error,
230
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
231
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
232
0
     "%s: byte stream too small.",
233
0
     function );
234
235
0
    return( -1 );
236
0
  }
237
0
  if( unicode_character < 0x0080 )
238
0
  {
239
0
    byte_stream_value = (uint16_t) unicode_character;
240
0
  }
241
0
  else if( ( unicode_character >= 0x00a0 )
242
0
        && ( unicode_character < 0x00d0 ) )
243
0
  {
244
0
    byte_stream_value = (uint16_t) unicode_character;
245
0
  }
246
0
  else if( ( unicode_character >= 0x00d0 )
247
0
        && ( unicode_character < 0x0100 ) )
248
0
  {
249
0
    unicode_character -= 0x00d0;
250
251
0
    byte_stream_value = libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x00d0[ unicode_character ];
252
0
  }
253
0
  else if( ( unicode_character >= 0x2010 )
254
0
        && ( unicode_character < 0x2028 ) )
255
0
  {
256
0
    unicode_character -= 0x2010;
257
258
0
    byte_stream_value = libuna_codepage_windows_1254_unicode_to_byte_stream_base_0x2010[ unicode_character ];
259
0
  }
260
0
  else switch( unicode_character )
261
0
  {
262
0
    case 0x011e:
263
0
      byte_stream_value = 0xd0;
264
0
      break;
265
266
0
    case 0x011f:
267
0
      byte_stream_value = 0xf0;
268
0
      break;
269
270
0
    case 0x0130:
271
0
      byte_stream_value = 0xdd;
272
0
      break;
273
274
0
    case 0x0131:
275
0
      byte_stream_value = 0xfd;
276
0
      break;
277
278
0
    case 0x0152:
279
0
      byte_stream_value = 0x8c;
280
0
      break;
281
282
0
    case 0x0153:
283
0
      byte_stream_value = 0x9c;
284
0
      break;
285
286
0
    case 0x015e:
287
0
      byte_stream_value = 0xde;
288
0
      break;
289
290
0
    case 0x015f:
291
0
      byte_stream_value = 0xfe;
292
0
      break;
293
294
0
    case 0x0160:
295
0
      byte_stream_value = 0x8a;
296
0
      break;
297
298
0
    case 0x0161:
299
0
      byte_stream_value = 0x9a;
300
0
      break;
301
302
0
    case 0x0178:
303
0
      byte_stream_value = 0x9f;
304
0
      break;
305
306
0
    case 0x0192:
307
0
      byte_stream_value = 0x83;
308
0
      break;
309
310
0
    case 0x02c6:
311
0
      byte_stream_value = 0x88;
312
0
      break;
313
314
0
    case 0x02dc:
315
0
      byte_stream_value = 0x98;
316
0
      break;
317
318
0
    case 0x2030:
319
0
      byte_stream_value = 0x89;
320
0
      break;
321
322
0
    case 0x2039:
323
0
      byte_stream_value = 0x8b;
324
0
      break;
325
326
0
    case 0x203a:
327
0
      byte_stream_value = 0x9b;
328
0
      break;
329
330
0
    case 0x20ac:
331
0
      byte_stream_value = 0x80;
332
0
      break;
333
334
0
    case 0x2122:
335
0
      byte_stream_value = 0x99;
336
0
      break;
337
338
0
    default:
339
0
      byte_stream_value = 0x1a;
340
0
      break;
341
0
  }
342
0
  byte_stream[ safe_byte_stream_index++ ] = (uint8_t) ( byte_stream_value & 0x00ff );
343
344
0
  *byte_stream_index = safe_byte_stream_index;
345
346
0
  return( 1 );
347
0
}
348