Coverage Report

Created: 2024-10-02 06:58

/src/libfsapfs/libfsapfs/libfsapfs_name_hash.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Name hash functions
3
 *
4
 * Copyright (C) 2018-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 <memory.h>
24
#include <types.h>
25
26
#include "libfsapfs_checksum.h"
27
#include "libfsapfs_libcerror.h"
28
#include "libfsapfs_libcnotify.h"
29
#include "libfsapfs_libuna.h"
30
#include "libfsapfs_name.h"
31
32
libfsapfs_name_decomposition_mapping_t special_case_folding_000000df = { 2, { 0x00000073, 0x00000073 } };
33
libfsapfs_name_decomposition_mapping_t special_case_folding_00000130 = { 2, { 0x00000069, 0x00000307 } };
34
libfsapfs_name_decomposition_mapping_t special_case_folding_00000149 = { 2, { 0x000002bc, 0x0000006e } };
35
libfsapfs_name_decomposition_mapping_t special_case_folding_00000587 = { 2, { 0x00000565, 0x00000582 } };
36
libfsapfs_name_decomposition_mapping_t special_case_folding_00001e9a = { 2, { 0x00000061, 0x000002be } };
37
38
libfsapfs_name_decomposition_mapping_t special_case_folding_00001f80[ 48 ] = {
39
  /* 00001f80 */ { 3, { 0x000003b1, 0x00000313, 0x000003b9 } },
40
  /* 00001f81 */ { 3, { 0x000003b1, 0x00000314, 0x000003b9 } },
41
  /* 00001f82 */ { 4, { 0x000003b1, 0x00000313, 0x00000300, 0x000003b9 } },
42
  /* 00001f83 */ { 4, { 0x000003b1, 0x00000314, 0x00000300, 0x000003b9 } },
43
  /* 00001f84 */ { 4, { 0x000003b1, 0x00000313, 0x00000301, 0x000003b9 } },
44
  /* 00001f85 */ { 4, { 0x000003b1, 0x00000314, 0x00000301, 0x000003b9 } },
45
  /* 00001f86 */ { 4, { 0x000003b1, 0x00000313, 0x00000342, 0x000003b9 } },
46
  /* 00001f87 */ { 4, { 0x000003b1, 0x00000314, 0x00000342, 0x000003b9 } },
47
  /* 00001f88 */ { 3, { 0x000003b1, 0x00000313, 0x000003b9 } },
48
  /* 00001f89 */ { 3, { 0x000003b1, 0x00000314, 0x000003b9 } },
49
  /* 00001f8a */ { 4, { 0x000003b1, 0x00000313, 0x00000300, 0x000003b9 } },
50
  /* 00001f8b */ { 4, { 0x000003b1, 0x00000314, 0x00000300, 0x000003b9 } },
51
  /* 00001f8c */ { 4, { 0x000003b1, 0x00000313, 0x00000301, 0x000003b9 } },
52
  /* 00001f8d */ { 4, { 0x000003b1, 0x00000314, 0x00000301, 0x000003b9 } },
53
  /* 00001f8e */ { 4, { 0x000003b1, 0x00000313, 0x00000342, 0x000003b9 } },
54
  /* 00001f8f */ { 4, { 0x000003b1, 0x00000314, 0x00000342, 0x000003b9 } },
55
  /* 00001f90 */ { 3, { 0x000003b7, 0x00000313, 0x000003b9 } },
56
  /* 00001f91 */ { 3, { 0x000003b7, 0x00000314, 0x000003b9 } },
57
  /* 00001f92 */ { 4, { 0x000003b7, 0x00000313, 0x00000300, 0x000003b9 } },
58
  /* 00001f93 */ { 4, { 0x000003b7, 0x00000314, 0x00000300, 0x000003b9 } },
59
  /* 00001f94 */ { 4, { 0x000003b7, 0x00000313, 0x00000301, 0x000003b9 } },
60
  /* 00001f95 */ { 4, { 0x000003b7, 0x00000314, 0x00000301, 0x000003b9 } },
61
  /* 00001f96 */ { 4, { 0x000003b7, 0x00000313, 0x00000342, 0x000003b9 } },
62
  /* 00001f97 */ { 4, { 0x000003b7, 0x00000314, 0x00000342, 0x000003b9 } },
63
  /* 00001f98 */ { 3, { 0x000003b7, 0x00000313, 0x000003b9 } },
64
  /* 00001f99 */ { 3, { 0x000003b7, 0x00000314, 0x000003b9 } },
65
  /* 00001f9a */ { 4, { 0x000003b7, 0x00000313, 0x00000300, 0x000003b9 } },
66
  /* 00001f9b */ { 4, { 0x000003b7, 0x00000314, 0x00000300, 0x000003b9 } },
67
  /* 00001f9c */ { 4, { 0x000003b7, 0x00000313, 0x00000301, 0x000003b9 } },
68
  /* 00001f9d */ { 4, { 0x000003b7, 0x00000314, 0x00000301, 0x000003b9 } },
69
  /* 00001f9e */ { 4, { 0x000003b7, 0x00000313, 0x00000342, 0x000003b9 } },
70
  /* 00001f9f */ { 4, { 0x000003b7, 0x00000314, 0x00000342, 0x000003b9 } },
71
  /* 00001fa0 */ { 3, { 0x000003c9, 0x00000313, 0x000003b9 } },
72
  /* 00001fa1 */ { 3, { 0x000003c9, 0x00000314, 0x000003b9 } },
73
  /* 00001fa2 */ { 4, { 0x000003c9, 0x00000313, 0x00000300, 0x000003b9 } },
74
  /* 00001fa3 */ { 4, { 0x000003c9, 0x00000314, 0x00000300, 0x000003b9 } },
75
  /* 00001fa4 */ { 4, { 0x000003c9, 0x00000313, 0x00000301, 0x000003b9 } },
76
  /* 00001fa5 */ { 4, { 0x000003c9, 0x00000314, 0x00000301, 0x000003b9 } },
77
  /* 00001fa6 */ { 4, { 0x000003c9, 0x00000313, 0x00000342, 0x000003b9 } },
78
  /* 00001fa7 */ { 4, { 0x000003c9, 0x00000314, 0x00000342, 0x000003b9 } },
79
  /* 00001fa8 */ { 3, { 0x000003c9, 0x00000313, 0x000003b9 } },
80
  /* 00001fa9 */ { 3, { 0x000003c9, 0x00000314, 0x000003b9 } },
81
  /* 00001faa */ { 4, { 0x000003c9, 0x00000313, 0x00000300, 0x000003b9 } },
82
  /* 00001fab */ { 4, { 0x000003c9, 0x00000314, 0x00000300, 0x000003b9 } },
83
  /* 00001fac */ { 4, { 0x000003c9, 0x00000313, 0x00000301, 0x000003b9 } },
84
  /* 00001fad */ { 4, { 0x000003c9, 0x00000314, 0x00000301, 0x000003b9 } },
85
  /* 00001fae */ { 4, { 0x000003c9, 0x00000313, 0x00000342, 0x000003b9 } },
86
  /* 00001faf */ { 4, { 0x000003c9, 0x00000314, 0x00000342, 0x000003b9 } }
87
};
88
89
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fb2 = { 3, { 0x000003b1, 0x00000300, 0x000003b9 } };
90
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fb3 = { 2, { 0x000003b1, 0x000003b9 } };
91
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fb4 = { 3, { 0x000003b1, 0x00000301, 0x000003b9 } };
92
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fb6 = { 2, { 0x000003b1, 0x00000342 } };
93
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fb7 = { 3, { 0x000003b1, 0x00000342, 0x000003b9 } };
94
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fbc = { 2, { 0x000003b1, 0x000003b9 } };
95
96
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fc2 = { 3, { 0x000003b7, 0x00000300, 0x000003b9 } };
97
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fc3 = { 2, { 0x000003b7, 0x000003b9 } };
98
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fc4 = { 3, { 0x000003b7, 0x00000301, 0x000003b9 } };
99
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fc6 = { 2, { 0x000003b7, 0x00000342 } };
100
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fc7 = { 3, { 0x000003b7, 0x00000342, 0x000003b9 } };
101
libfsapfs_name_decomposition_mapping_t special_case_folding_00001fcc = { 2, { 0x000003b7, 0x000003b9 } };
102
103
libfsapfs_name_decomposition_mapping_t special_case_folding_00001ff2 = { 3, { 0x000003c9, 0x00000300, 0x000003b9 } };
104
libfsapfs_name_decomposition_mapping_t special_case_folding_00001ff3 = { 2, { 0x000003c9, 0x000003b9 } };
105
libfsapfs_name_decomposition_mapping_t special_case_folding_00001ff4 = { 3, { 0x000003c9, 0x00000301, 0x000003b9 } };
106
libfsapfs_name_decomposition_mapping_t special_case_folding_00001ff6 = { 2, { 0x000003c9, 0x00000342 } };
107
libfsapfs_name_decomposition_mapping_t special_case_folding_00001ff7 = { 3, { 0x000003c9, 0x00000342, 0x000003b9 } };
108
libfsapfs_name_decomposition_mapping_t special_case_folding_00001ffc = { 2, { 0x000003c9, 0x000003b9 } };
109
110
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb00 = { 2, { 0x00000066, 0x00000066 } };
111
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb01 = { 2, { 0x00000066, 0x00000069 } };
112
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb02 = { 2, { 0x00000066, 0x0000006c } };
113
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb03 = { 3, { 0x00000066, 0x00000066, 0x00000069 } };
114
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb04 = { 3, { 0x00000066, 0x00000066, 0x0000006c } };
115
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb05 = { 2, { 0x00000073, 0x00000074 } };
116
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb06 = { 2, { 0x00000073, 0x00000074 } };
117
118
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb13 = { 2, { 0x00000574, 0x00000576 } };
119
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb14 = { 2, { 0x00000574, 0x00000565 } };
120
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb15 = { 2, { 0x00000574, 0x0000056b } };
121
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb16 = { 2, { 0x0000057e, 0x00000576 } };
122
libfsapfs_name_decomposition_mapping_t special_case_folding_0000fb17 = { 2, { 0x00000574, 0x0000056d } };
123
124
/* Calculates the name hash of an UTF-8 formatted string
125
 * Returns 1 if successful or -1 on error
126
 */
127
int libfsapfs_name_hash_calculate_from_utf8_string(
128
     uint32_t *name_hash,
129
     const uint8_t *utf8_string,
130
     size_t utf8_string_length,
131
     uint8_t use_case_folding,
132
     libcerror_error_t **error )
133
1.25k
{
134
1.25k
  libfsapfs_name_decomposition_mapping_t single_nfd_mapping = { 1, { 0 } };
135
136
1.25k
  libfsapfs_name_decomposition_mapping_t *nfd_mapping       = NULL;
137
1.25k
  static char *function                                     = "libfsapfs_name_hash_calculate_from_utf8_string";
138
1.25k
  libuna_unicode_character_t unicode_character              = 0;
139
1.25k
  size_t utf8_string_index                                  = 0;
140
1.25k
  uint32_t calculated_checksum                              = 0;
141
1.25k
  uint32_t checksum_table_index                             = 0;
142
1.25k
  uint8_t byte_value                                        = 0;
143
1.25k
  uint8_t nfd_character_index                               = 0;
144
145
#if defined( HAVE_DEBUG_OUTPUT )
146
  uint8_t utf32_stream[ 512 ];
147
148
  size_t utf32_stream_index                                 = 0;
149
#endif
150
151
1.25k
  if( name_hash == NULL )
152
0
  {
153
0
    libcerror_error_set(
154
0
     error,
155
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
156
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
157
0
     "%s: invalid name hash.",
158
0
     function );
159
160
0
    return( -1 );
161
0
  }
162
1.25k
  if( libfsapfs_checksum_crc32_table_computed == 0 )
163
1
  {
164
1
    libfsapfs_checksum_initialize_crc32_table(
165
1
     0x82f63b78UL );
166
1
  }
167
1.25k
  calculated_checksum = 0xffffffffUL;
168
169
13.0k
  while( utf8_string_index < utf8_string_length )
170
11.7k
  {
171
11.7k
    if( libuna_unicode_character_copy_from_utf8(
172
11.7k
         &unicode_character,
173
11.7k
         utf8_string,
174
11.7k
         utf8_string_length,
175
11.7k
         &utf8_string_index,
176
11.7k
         error ) != 1 )
177
0
    {
178
0
      libcerror_error_set(
179
0
       error,
180
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
181
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
182
0
       "%s: unable to copy Unicode character from UTF-8 string.",
183
0
       function );
184
185
0
      return( -1 );
186
0
    }
187
11.7k
    if( unicode_character == 0 )
188
0
    {
189
0
      break;
190
0
    }
191
11.7k
    if( use_case_folding != 0 )
192
11.7k
    {
193
11.7k
      libfsapfs_name_get_case_folding_mapping(
194
11.7k
       unicode_character );
195
196
      /* Overload the NFD mapping to handle special case folding
197
       */
198
11.7k
      if( ( unicode_character >= 0x00001f80UL )
199
11.7k
       && ( unicode_character <= 0x00001fafUL ) )
200
0
      {
201
0
        nfd_mapping = &( special_case_folding_00001f80[ unicode_character - 0x00001f80UL ] );
202
0
      }
203
11.7k
      else switch( unicode_character )
204
11.7k
      {
205
0
        case 0x000000dfUL:
206
0
          nfd_mapping = &special_case_folding_000000df;
207
0
          break;
208
209
0
        case 0x00000130UL:
210
0
          nfd_mapping = &special_case_folding_00000130;
211
0
          break;
212
213
0
        case 0x00000149UL:
214
0
          nfd_mapping = &special_case_folding_00000149;
215
0
          break;
216
217
0
        case 0x00000587UL:
218
0
          nfd_mapping = &special_case_folding_00000587;
219
0
          break;
220
221
0
        case 0x00001e9aUL:
222
0
          nfd_mapping = &special_case_folding_00001e9a;
223
0
          break;
224
225
0
        case 0x00001fb2UL:
226
0
          nfd_mapping = &special_case_folding_00001fb2;
227
0
          break;
228
229
0
        case 0x00001fb3UL:
230
0
          nfd_mapping = &special_case_folding_00001fb3;
231
0
          break;
232
233
0
        case 0x00001fb4UL:
234
0
          nfd_mapping = &special_case_folding_00001fb4;
235
0
          break;
236
237
0
        case 0x00001fb6UL:
238
0
          nfd_mapping = &special_case_folding_00001fb6;
239
0
          break;
240
241
0
        case 0x00001fb7UL:
242
0
          nfd_mapping = &special_case_folding_00001fb7;
243
0
          break;
244
245
0
        case 0x00001fbcUL:
246
0
          nfd_mapping = &special_case_folding_00001fbc;
247
0
          break;
248
249
0
        case 0x00001fc2UL:
250
0
          nfd_mapping = &special_case_folding_00001fc2;
251
0
          break;
252
253
0
        case 0x00001fc3UL:
254
0
          nfd_mapping = &special_case_folding_00001fc3;
255
0
          break;
256
257
0
        case 0x00001fc4UL:
258
0
          nfd_mapping = &special_case_folding_00001fc4;
259
0
          break;
260
261
0
        case 0x00001fc6UL:
262
0
          nfd_mapping = &special_case_folding_00001fc6;
263
0
          break;
264
265
0
        case 0x00001fc7UL:
266
0
          nfd_mapping = &special_case_folding_00001fc7;
267
0
          break;
268
269
0
        case 0x00001fccUL:
270
0
          nfd_mapping = &special_case_folding_00001fcc;
271
0
          break;
272
273
0
        case 0x00001ff2UL:
274
0
          nfd_mapping = &special_case_folding_00001ff2;
275
0
          break;
276
277
0
        case 0x00001ff3UL:
278
0
          nfd_mapping = &special_case_folding_00001ff3;
279
0
          break;
280
281
0
        case 0x00001ff4UL:
282
0
          nfd_mapping = &special_case_folding_00001ff4;
283
0
          break;
284
285
0
        case 0x00001ff6UL:
286
0
          nfd_mapping = &special_case_folding_00001ff6;
287
0
          break;
288
289
0
        case 0x00001ff7UL:
290
0
          nfd_mapping = &special_case_folding_00001ff7;
291
0
          break;
292
293
0
        case 0x00001ffcUL:
294
0
          nfd_mapping = &special_case_folding_00001ffc;
295
0
          break;
296
297
0
        case 0x0000fb00UL:
298
0
          nfd_mapping = &special_case_folding_0000fb00;
299
0
          break;
300
301
0
        case 0x0000fb01UL:
302
0
          nfd_mapping = &special_case_folding_0000fb01;
303
0
          break;
304
305
0
        case 0x0000fb02UL:
306
0
          nfd_mapping = &special_case_folding_0000fb02;
307
0
          break;
308
309
0
        case 0x0000fb03UL:
310
0
          nfd_mapping = &special_case_folding_0000fb03;
311
0
          break;
312
313
0
        case 0x0000fb04UL:
314
0
          nfd_mapping = &special_case_folding_0000fb04;
315
0
          break;
316
317
0
        case 0x0000fb05UL:
318
0
          nfd_mapping = &special_case_folding_0000fb05;
319
0
          break;
320
321
0
        case 0x0000fb06UL:
322
0
          nfd_mapping = &special_case_folding_0000fb06;
323
0
          break;
324
325
0
        case 0x0000fb13UL:
326
0
          nfd_mapping = &special_case_folding_0000fb13;
327
0
          break;
328
329
0
        case 0x0000fb14UL:
330
0
          nfd_mapping = &special_case_folding_0000fb14;
331
0
          break;
332
333
0
        case 0x0000fb15UL:
334
0
          nfd_mapping = &special_case_folding_0000fb15;
335
0
          break;
336
337
0
        case 0x0000fb16UL:
338
0
          nfd_mapping = &special_case_folding_0000fb16;
339
0
          break;
340
341
0
        case 0x0000fb17UL:
342
0
          nfd_mapping = &special_case_folding_0000fb17;
343
0
          break;
344
345
11.7k
        default:
346
11.7k
          libfsapfs_name_get_decomposition_mapping(
347
11.7k
           unicode_character,
348
11.7k
           nfd_mapping,
349
11.7k
           single_nfd_mapping );
350
11.7k
          break;
351
11.7k
      }
352
11.7k
    }
353
0
    else
354
0
    {
355
0
      libfsapfs_name_get_decomposition_mapping(
356
0
       unicode_character,
357
0
       nfd_mapping,
358
0
       single_nfd_mapping );
359
0
    }
360
11.7k
    for( nfd_character_index = 0;
361
23.5k
         nfd_character_index < nfd_mapping->number_of_characters;
362
11.7k
         nfd_character_index++ )
363
11.7k
    {
364
11.7k
      unicode_character = nfd_mapping->characters[ nfd_character_index ];
365
366
11.7k
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
367
11.7k
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
368
11.7k
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
369
11.7k
      unicode_character  >>= 8;
370
371
#if defined( HAVE_DEBUG_OUTPUT )
372
      if( utf32_stream_index < 512 )
373
      {
374
        utf32_stream[ utf32_stream_index++ ] = byte_value;
375
      }
376
#endif
377
378
11.7k
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
379
11.7k
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
380
11.7k
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
381
11.7k
      unicode_character  >>= 8;
382
383
#if defined( HAVE_DEBUG_OUTPUT )
384
      if( utf32_stream_index < 512 )
385
      {
386
        utf32_stream[ utf32_stream_index++ ] = byte_value;
387
      }
388
#endif
389
390
11.7k
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
391
11.7k
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
392
11.7k
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
393
11.7k
      unicode_character  >>= 8;
394
395
#if defined( HAVE_DEBUG_OUTPUT )
396
      if( utf32_stream_index < 512 )
397
      {
398
        utf32_stream[ utf32_stream_index++ ] = byte_value;
399
      }
400
#endif
401
402
11.7k
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
403
11.7k
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
404
11.7k
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
405
406
#if defined( HAVE_DEBUG_OUTPUT )
407
      if( utf32_stream_index < 512 )
408
      {
409
        utf32_stream[ utf32_stream_index++ ] = byte_value;
410
      }
411
#endif
412
11.7k
    }
413
11.7k
  }
414
1.25k
  *name_hash = calculated_checksum & 0x003fffffUL;
415
416
#if defined( HAVE_DEBUG_OUTPUT )
417
  if( libcnotify_verbose != 0 )
418
  {
419
    libcnotify_printf(
420
     "%s: UTF-32 stream data:\n",
421
     function );
422
    libcnotify_print_data(
423
     utf32_stream,
424
     utf32_stream_index,
425
     0 );
426
427
    libcnotify_printf(
428
     "%s: CRC-32 checkum\t\t: 0x%08" PRIx32 "\n",
429
     function,
430
     calculated_checksum );
431
432
    libcnotify_printf(
433
     "%s: name hash\t\t: 0x%06" PRIx32 "\n",
434
     function,
435
     *name_hash );
436
437
    libcnotify_printf(
438
     "\n" );
439
  }
440
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
441
442
1.25k
  return( 1 );
443
1.25k
}
444
445
/* Calculates the name hash of an UTF-16 formatted string
446
 * Returns 1 if successful or -1 on error
447
 */
448
int libfsapfs_name_hash_calculate_from_utf16_string(
449
     uint32_t *name_hash,
450
     const uint16_t *utf16_string,
451
     size_t utf16_string_length,
452
     uint8_t use_case_folding,
453
     libcerror_error_t **error )
454
0
{
455
0
  libfsapfs_name_decomposition_mapping_t single_nfd_mapping = { 1, { 0 } };
456
457
0
  libfsapfs_name_decomposition_mapping_t *nfd_mapping       = NULL;
458
0
  static char *function                                     = "libfsapfs_name_hash_calculate_from_utf16_string";
459
0
  libuna_unicode_character_t unicode_character              = 0;
460
0
  size_t utf16_string_index                                 = 0;
461
0
  uint32_t calculated_checksum                              = 0;
462
0
  uint32_t checksum_table_index                             = 0;
463
0
  uint8_t byte_value                                        = 0;
464
0
  uint8_t nfd_character_index                               = 0;
465
466
#if defined( HAVE_DEBUG_OUTPUT )
467
  uint8_t utf32_stream[ 512 ];
468
469
  size_t utf32_stream_index                                 = 0;
470
#endif
471
472
0
  if( name_hash == NULL )
473
0
  {
474
0
    libcerror_error_set(
475
0
     error,
476
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
477
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
478
0
     "%s: invalid name hash.",
479
0
     function );
480
481
0
    return( -1 );
482
0
  }
483
0
  if( libfsapfs_checksum_crc32_table_computed == 0 )
484
0
  {
485
0
    libfsapfs_checksum_initialize_crc32_table(
486
0
     0x82f63b78UL );
487
0
  }
488
0
  calculated_checksum = 0xffffffffUL;
489
490
0
  while( utf16_string_index < utf16_string_length )
491
0
  {
492
0
    if( libuna_unicode_character_copy_from_utf16(
493
0
         &unicode_character,
494
0
         utf16_string,
495
0
         utf16_string_length,
496
0
         &utf16_string_index,
497
0
         error ) != 1 )
498
0
    {
499
0
      libcerror_error_set(
500
0
       error,
501
0
       LIBCERROR_ERROR_DOMAIN_CONVERSION,
502
0
       LIBCERROR_CONVERSION_ERROR_INPUT_FAILED,
503
0
       "%s: unable to copy Unicode character from UTF-16 string.",
504
0
       function );
505
506
0
      return( -1 );
507
0
    }
508
0
    if( unicode_character == 0 )
509
0
    {
510
0
      break;
511
0
    }
512
0
    if( use_case_folding != 0 )
513
0
    {
514
0
      libfsapfs_name_get_case_folding_mapping(
515
0
       unicode_character );
516
517
      /* Overload the NFD mapping to handle special case folding
518
       */
519
0
      if( ( unicode_character >= 0x00001f80UL )
520
0
       && ( unicode_character <= 0x00001fafUL ) )
521
0
      {
522
0
        nfd_mapping = &( special_case_folding_00001f80[ unicode_character - 0x00001f80UL ] );
523
0
      }
524
0
      else switch( unicode_character )
525
0
      {
526
0
        case 0x000000dfUL:
527
0
          nfd_mapping = &special_case_folding_000000df;
528
0
          break;
529
530
0
        case 0x00000130UL:
531
0
          nfd_mapping = &special_case_folding_00000130;
532
0
          break;
533
534
0
        case 0x00000149UL:
535
0
          nfd_mapping = &special_case_folding_00000149;
536
0
          break;
537
538
0
        case 0x00000587UL:
539
0
          nfd_mapping = &special_case_folding_00000587;
540
0
          break;
541
542
0
        case 0x00001e9aUL:
543
0
          nfd_mapping = &special_case_folding_00001e9a;
544
0
          break;
545
546
0
        case 0x00001fb2UL:
547
0
          nfd_mapping = &special_case_folding_00001fb2;
548
0
          break;
549
550
0
        case 0x00001fb3UL:
551
0
          nfd_mapping = &special_case_folding_00001fb3;
552
0
          break;
553
554
0
        case 0x00001fb4UL:
555
0
          nfd_mapping = &special_case_folding_00001fb4;
556
0
          break;
557
558
0
        case 0x00001fb6UL:
559
0
          nfd_mapping = &special_case_folding_00001fb6;
560
0
          break;
561
562
0
        case 0x00001fb7UL:
563
0
          nfd_mapping = &special_case_folding_00001fb7;
564
0
          break;
565
566
0
        case 0x00001fbcUL:
567
0
          nfd_mapping = &special_case_folding_00001fbc;
568
0
          break;
569
570
0
        case 0x00001fc2UL:
571
0
          nfd_mapping = &special_case_folding_00001fc2;
572
0
          break;
573
574
0
        case 0x00001fc3UL:
575
0
          nfd_mapping = &special_case_folding_00001fc3;
576
0
          break;
577
578
0
        case 0x00001fc4UL:
579
0
          nfd_mapping = &special_case_folding_00001fc4;
580
0
          break;
581
582
0
        case 0x00001fc6UL:
583
0
          nfd_mapping = &special_case_folding_00001fc6;
584
0
          break;
585
586
0
        case 0x00001fc7UL:
587
0
          nfd_mapping = &special_case_folding_00001fc7;
588
0
          break;
589
590
0
        case 0x00001fccUL:
591
0
          nfd_mapping = &special_case_folding_00001fcc;
592
0
          break;
593
594
0
        case 0x00001ff2UL:
595
0
          nfd_mapping = &special_case_folding_00001ff2;
596
0
          break;
597
598
0
        case 0x00001ff3UL:
599
0
          nfd_mapping = &special_case_folding_00001ff3;
600
0
          break;
601
602
0
        case 0x00001ff4UL:
603
0
          nfd_mapping = &special_case_folding_00001ff4;
604
0
          break;
605
606
0
        case 0x00001ff6UL:
607
0
          nfd_mapping = &special_case_folding_00001ff6;
608
0
          break;
609
610
0
        case 0x00001ff7UL:
611
0
          nfd_mapping = &special_case_folding_00001ff7;
612
0
          break;
613
614
0
        case 0x00001ffcUL:
615
0
          nfd_mapping = &special_case_folding_00001ffc;
616
0
          break;
617
618
0
        case 0x0000fb00UL:
619
0
          nfd_mapping = &special_case_folding_0000fb00;
620
0
          break;
621
622
0
        case 0x0000fb01UL:
623
0
          nfd_mapping = &special_case_folding_0000fb01;
624
0
          break;
625
626
0
        case 0x0000fb02UL:
627
0
          nfd_mapping = &special_case_folding_0000fb02;
628
0
          break;
629
630
0
        case 0x0000fb03UL:
631
0
          nfd_mapping = &special_case_folding_0000fb03;
632
0
          break;
633
634
0
        case 0x0000fb04UL:
635
0
          nfd_mapping = &special_case_folding_0000fb04;
636
0
          break;
637
638
0
        case 0x0000fb05UL:
639
0
          nfd_mapping = &special_case_folding_0000fb05;
640
0
          break;
641
642
0
        case 0x0000fb06UL:
643
0
          nfd_mapping = &special_case_folding_0000fb06;
644
0
          break;
645
646
0
        case 0x0000fb13UL:
647
0
          nfd_mapping = &special_case_folding_0000fb13;
648
0
          break;
649
650
0
        case 0x0000fb14UL:
651
0
          nfd_mapping = &special_case_folding_0000fb14;
652
0
          break;
653
654
0
        case 0x0000fb15UL:
655
0
          nfd_mapping = &special_case_folding_0000fb15;
656
0
          break;
657
658
0
        case 0x0000fb16UL:
659
0
          nfd_mapping = &special_case_folding_0000fb16;
660
0
          break;
661
662
0
        case 0x0000fb17UL:
663
0
          nfd_mapping = &special_case_folding_0000fb17;
664
0
          break;
665
666
0
        default:
667
0
          libfsapfs_name_get_decomposition_mapping(
668
0
           unicode_character,
669
0
           nfd_mapping,
670
0
           single_nfd_mapping );
671
0
          break;
672
0
      }
673
0
    }
674
0
    else
675
0
    {
676
0
      libfsapfs_name_get_decomposition_mapping(
677
0
       unicode_character,
678
0
       nfd_mapping,
679
0
       single_nfd_mapping );
680
0
    }
681
0
    for( nfd_character_index = 0;
682
0
         nfd_character_index < nfd_mapping->number_of_characters;
683
0
         nfd_character_index++ )
684
0
    {
685
0
      unicode_character = nfd_mapping->characters[ nfd_character_index ];
686
687
0
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
688
0
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
689
0
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
690
0
      unicode_character  >>= 8;
691
692
#if defined( HAVE_DEBUG_OUTPUT )
693
      if( utf32_stream_index < 512 )
694
      {
695
        utf32_stream[ utf32_stream_index++ ] = byte_value;
696
      }
697
#endif
698
699
0
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
700
0
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
701
0
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
702
0
      unicode_character  >>= 8;
703
704
#if defined( HAVE_DEBUG_OUTPUT )
705
      if( utf32_stream_index < 512 )
706
      {
707
        utf32_stream[ utf32_stream_index++ ] = byte_value;
708
      }
709
#endif
710
711
0
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
712
0
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
713
0
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
714
0
      unicode_character  >>= 8;
715
716
#if defined( HAVE_DEBUG_OUTPUT )
717
      if( utf32_stream_index < 512 )
718
      {
719
        utf32_stream[ utf32_stream_index++ ] = byte_value;
720
      }
721
#endif
722
723
0
      byte_value           = (uint8_t) ( unicode_character & 0x000000ffUL );
724
0
      checksum_table_index = ( calculated_checksum ^ (uint32_t) byte_value ) & 0x000000ffUL;
725
0
      calculated_checksum  = libfsapfs_checksum_crc32_table[ checksum_table_index ] ^ ( calculated_checksum >> 8 );
726
727
#if defined( HAVE_DEBUG_OUTPUT )
728
      if( utf32_stream_index < 512 )
729
      {
730
        utf32_stream[ utf32_stream_index++ ] = byte_value;
731
      }
732
#endif
733
0
    }
734
0
  }
735
0
  *name_hash = calculated_checksum & 0x003fffffUL;
736
737
#if defined( HAVE_DEBUG_OUTPUT )
738
  if( libcnotify_verbose != 0 )
739
  {
740
    libcnotify_printf(
741
     "%s: UTF-32 stream data:\n",
742
     function );
743
    libcnotify_print_data(
744
     utf32_stream,
745
     utf32_stream_index,
746
     0 );
747
748
    libcnotify_printf(
749
     "%s: CRC-32 checkum\t\t: 0x%08" PRIx32 "\n",
750
     function,
751
     calculated_checksum );
752
753
    libcnotify_printf(
754
     "%s: name hash\t\t: 0x%06" PRIx32 "\n",
755
     function,
756
     *name_hash );
757
758
    libcnotify_printf(
759
     "\n" );
760
  }
761
#endif /* defined( HAVE_DEBUG_OUTPUT ) */
762
763
0
  return( 1 );
764
0
}
765