clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name cpdtrans.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D V8_DEPRECATION_WARNINGS -D V8_IMMINENT_DEPRECATION_WARNINGS -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D U_COMMON_IMPLEMENTATION=1 -D U_I18N_IMPLEMENTATION=1 -D U_IO_IMPLEMENTATION=1 -D U_TOOLUTIL_IMPLEMENTATION=1 -D U_ATTRIBUTE_DEPRECATED= -D _CRT_SECURE_NO_DEPRECATE= -D U_STATIC_IMPLEMENTATION=1 -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -I ../deps/icu-small/source/common -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/tools/toolutil -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-deprecated-declarations -Wno-strict-aliasing -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../deps/icu-small/source/i18n/cpdtrans.cpp
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #include "unicode/utypes.h" |
14 | |
15 | #if !UCONFIG_NO_TRANSLITERATION |
16 | |
17 | #include "unicode/unifilt.h" |
18 | #include "unicode/uniset.h" |
19 | #include "cpdtrans.h" |
20 | #include "uvector.h" |
21 | #include "tridpars.h" |
22 | #include "cmemory.h" |
23 | |
24 | |
25 | |
26 | static const UChar ID_DELIM = 0x003B; |
27 | static const UChar NEWLINE = 10; |
28 | |
29 | static const UChar COLON_COLON[] = {0x3A, 0x3A, 0}; |
30 | |
31 | U_NAMESPACE_BEGIN |
32 | |
33 | const UChar CompoundTransliterator::PASS_STRING[] = { 0x0025, 0x0050, 0x0061, 0x0073, 0x0073, 0 }; |
34 | |
35 | UOBJECT_DEFINE_RTTI_IMPLEMENTATION(CompoundTransliterator) |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | CompoundTransliterator::CompoundTransliterator( |
52 | Transliterator* const transliterators[], |
53 | int32_t transliteratorCount, |
54 | UnicodeFilter* adoptedFilter) : |
55 | Transliterator(joinIDs(transliterators, transliteratorCount), adoptedFilter), |
56 | trans(0), count(0), numAnonymousRBTs(0) { |
57 | setTransliterators(transliterators, transliteratorCount); |
| 1 | Calling 'CompoundTransliterator::setTransliterators' | |
|
58 | } |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | CompoundTransliterator::CompoundTransliterator(const UnicodeString& id, |
68 | UTransDirection direction, |
69 | UnicodeFilter* adoptedFilter, |
70 | UParseError& , |
71 | UErrorCode& status) : |
72 | Transliterator(id, adoptedFilter), |
73 | trans(0), numAnonymousRBTs(0) { |
74 | |
75 | |
76 | init(id, direction, TRUE, status); |
77 | } |
78 | |
79 | CompoundTransliterator::CompoundTransliterator(const UnicodeString& id, |
80 | UParseError& , |
81 | UErrorCode& status) : |
82 | Transliterator(id, 0), |
83 | trans(0), numAnonymousRBTs(0) { |
84 | |
85 | |
86 | init(id, UTRANS_FORWARD, TRUE, status); |
87 | } |
88 | |
89 | |
90 | |
91 | |
92 | |
93 | CompoundTransliterator::CompoundTransliterator(const UnicodeString& newID, |
94 | UVector& list, |
95 | UnicodeFilter* adoptedFilter, |
96 | int32_t anonymousRBTs, |
97 | UParseError& , |
98 | UErrorCode& status) : |
99 | Transliterator(newID, adoptedFilter), |
100 | trans(0), numAnonymousRBTs(anonymousRBTs) |
101 | { |
102 | init(list, UTRANS_FORWARD, FALSE, status); |
103 | } |
104 | |
105 | |
106 | |
107 | |
108 | |
109 | |
110 | CompoundTransliterator::CompoundTransliterator(UVector& list, |
111 | UParseError& , |
112 | UErrorCode& status) : |
113 | Transliterator(UnicodeString(), NULL), |
114 | trans(0), numAnonymousRBTs(0) |
115 | { |
116 | |
117 | |
118 | init(list, UTRANS_FORWARD, FALSE, status); |
119 | |
120 | } |
121 | |
122 | CompoundTransliterator::CompoundTransliterator(UVector& list, |
123 | int32_t anonymousRBTs, |
124 | UParseError& , |
125 | UErrorCode& status) : |
126 | Transliterator(UnicodeString(), NULL), |
127 | trans(0), numAnonymousRBTs(anonymousRBTs) |
128 | { |
129 | init(list, UTRANS_FORWARD, FALSE, status); |
130 | } |
131 | |
132 | |
133 | |
134 | |
135 | |
136 | |
137 | |
138 | |
139 | |
140 | |
141 | |
142 | |
143 | |
144 | |
145 | |
146 | |
147 | |
148 | void CompoundTransliterator::init(const UnicodeString& id, |
149 | UTransDirection direction, |
150 | UBool fixReverseID, |
151 | UErrorCode& status) { |
152 | |
153 | |
154 | if (U_FAILURE(status)) { |
155 | return; |
156 | } |
157 | |
158 | UVector list(status); |
159 | UnicodeSet* compoundFilter = NULL; |
160 | UnicodeString regenID; |
161 | if (!TransliteratorIDParser::parseCompoundID(id, direction, |
162 | regenID, list, compoundFilter)) { |
163 | status = U_INVALID_ID; |
164 | delete compoundFilter; |
165 | return; |
166 | } |
167 | |
168 | TransliteratorIDParser::instantiateList(list, status); |
169 | |
170 | init(list, direction, fixReverseID, status); |
171 | |
172 | if (compoundFilter != NULL) { |
173 | adoptFilter(compoundFilter); |
174 | } |
175 | } |
176 | |
177 | |
178 | |
179 | |
180 | |
181 | |
182 | |
183 | |
184 | |
185 | |
186 | |
187 | |
188 | |
189 | |
190 | void CompoundTransliterator::init(UVector& list, |
191 | UTransDirection direction, |
192 | UBool fixReverseID, |
193 | UErrorCode& status) { |
194 | |
195 | |
196 | |
197 | if (U_SUCCESS(status)) { |
198 | count = list.size(); |
199 | trans = (Transliterator **)uprv_malloc(count * sizeof(Transliterator *)); |
200 | |
201 | if (trans == 0) { |
202 | status = U_MEMORY_ALLOCATION_ERROR; |
203 | return; |
204 | } |
205 | } |
206 | |
207 | if (U_FAILURE(status) || trans == 0) { |
208 | |
209 | return; |
210 | } |
211 | |
212 | |
213 | |
214 | int32_t i; |
215 | for (i=0; i<count; ++i) { |
216 | int32_t j = (direction == UTRANS_FORWARD) ? i : count - 1 - i; |
217 | trans[i] = (Transliterator*) list.elementAt(j); |
218 | } |
219 | |
220 | |
221 | |
222 | if (direction == UTRANS_REVERSE && fixReverseID) { |
223 | UnicodeString newID; |
224 | for (i=0; i<count; ++i) { |
225 | if (i > 0) { |
226 | newID.append(ID_DELIM); |
227 | } |
228 | newID.append(trans[i]->getID()); |
229 | } |
230 | setID(newID); |
231 | } |
232 | |
233 | computeMaximumContextLength(); |
234 | } |
235 | |
236 | |
237 | |
238 | |
239 | |
240 | |
241 | UnicodeString CompoundTransliterator::joinIDs(Transliterator* const transliterators[], |
242 | int32_t transCount) { |
243 | UnicodeString id; |
244 | for (int32_t i=0; i<transCount; ++i) { |
245 | if (i > 0) { |
246 | id.append(ID_DELIM); |
247 | } |
248 | id.append(transliterators[i]->getID()); |
249 | } |
250 | return id; |
251 | } |
252 | |
253 | |
254 | |
255 | |
256 | CompoundTransliterator::CompoundTransliterator(const CompoundTransliterator& t) : |
257 | Transliterator(t), trans(0), count(0), numAnonymousRBTs(-1) { |
258 | *this = t; |
259 | } |
260 | |
261 | |
262 | |
263 | |
264 | CompoundTransliterator::~CompoundTransliterator() { |
265 | freeTransliterators(); |
266 | } |
267 | |
268 | void CompoundTransliterator::freeTransliterators(void) { |
269 | if (trans != 0) { |
270 | for (int32_t i=0; i<count; ++i) { |
271 | delete trans[i]; |
272 | } |
273 | uprv_free(trans); |
274 | } |
275 | trans = 0; |
276 | count = 0; |
277 | } |
278 | |
279 | |
280 | |
281 | |
282 | CompoundTransliterator& CompoundTransliterator::operator=( |
283 | const CompoundTransliterator& t) |
284 | { |
285 | if (this == &t) { return *this; } |
286 | Transliterator::operator=(t); |
287 | int32_t i = 0; |
288 | UBool failed = FALSE; |
289 | if (trans != NULL) { |
290 | for (i=0; i<count; ++i) { |
291 | delete trans[i]; |
292 | trans[i] = 0; |
293 | } |
294 | } |
295 | if (t.count > count) { |
296 | if (trans != NULL) { |
297 | uprv_free(trans); |
298 | } |
299 | trans = (Transliterator **)uprv_malloc(t.count * sizeof(Transliterator *)); |
300 | } |
301 | count = t.count; |
302 | if (trans != NULL) { |
303 | for (i=0; i<count; ++i) { |
304 | trans[i] = t.trans[i]->clone(); |
305 | if (trans[i] == NULL) { |
306 | failed = TRUE; |
307 | break; |
308 | } |
309 | } |
310 | } |
311 | |
312 | |
313 | if (failed && i > 0) { |
314 | int32_t n; |
315 | for (n = i-1; n >= 0; n--) { |
316 | uprv_free(trans[n]); |
317 | trans[n] = NULL; |
318 | } |
319 | } |
320 | numAnonymousRBTs = t.numAnonymousRBTs; |
321 | return *this; |
322 | } |
323 | |
324 | |
325 | |
326 | |
327 | CompoundTransliterator* CompoundTransliterator::clone() const { |
328 | return new CompoundTransliterator(*this); |
329 | } |
330 | |
331 | |
332 | |
333 | |
334 | |
335 | int32_t CompoundTransliterator::getCount(void) const { |
336 | return count; |
337 | } |
338 | |
339 | |
340 | |
341 | |
342 | |
343 | |
344 | const Transliterator& CompoundTransliterator::getTransliterator(int32_t index) const { |
345 | return *trans[index]; |
346 | } |
347 | |
348 | void CompoundTransliterator::setTransliterators(Transliterator* const transliterators[], |
349 | int32_t transCount) { |
350 | Transliterator** a = (Transliterator **)uprv_malloc(transCount * sizeof(Transliterator *)); |
351 | if (a == NULL) { |
| 2 | | Assuming 'a' is not equal to NULL | |
|
| |
352 | return; |
353 | } |
354 | int32_t i = 0; |
355 | UBool failed = FALSE; |
356 | for (i=0; i<transCount; ++i) { |
| 4 | | Assuming 'i' is < 'transCount' | |
|
| 5 | | Loop condition is true. Entering loop body | |
|
357 | a[i] = transliterators[i]->clone(); |
| |
358 | if (a[i] == NULL) { |
| 7 | | Assuming pointer value is null | |
|
| |
359 | failed = TRUE; |
360 | break; |
361 | } |
362 | } |
363 | if (failed && i > 0) { |
| |
364 | int32_t n; |
365 | for (n = i-1; n >= 0; n--) { |
366 | uprv_free(a[n]); |
367 | a[n] = NULL; |
368 | } |
369 | return; |
370 | } |
371 | adoptTransliterators(a, transCount); |
| 10 | | Calling 'CompoundTransliterator::adoptTransliterators' | |
|
372 | } |
373 | |
374 | void CompoundTransliterator::adoptTransliterators(Transliterator* adoptedTransliterators[], |
375 | int32_t transCount) { |
376 | |
377 | |
378 | freeTransliterators(); |
379 | trans = adoptedTransliterators; |
380 | count = transCount; |
381 | computeMaximumContextLength(); |
| 11 | | Calling 'CompoundTransliterator::computeMaximumContextLength' | |
|
382 | setID(joinIDs(trans, count)); |
383 | } |
384 | |
385 | |
386 | |
387 | |
388 | static void _smartAppend(UnicodeString& buf, UChar c) { |
389 | if (buf.length() != 0 && |
390 | buf.charAt(buf.length() - 1) != c) { |
391 | buf.append(c); |
392 | } |
393 | } |
394 | |
395 | UnicodeString& CompoundTransliterator::toRules(UnicodeString& rulesSource, |
396 | UBool escapeUnprintable) const { |
397 | |
398 | |
399 | |
400 | |
401 | |
402 | |
403 | rulesSource.truncate(0); |
404 | if (numAnonymousRBTs >= 1 && getFilter() != NULL) { |
405 | |
406 | |
407 | UnicodeString pat; |
408 | rulesSource.append(COLON_COLON, 2).append(getFilter()->toPattern(pat, escapeUnprintable)).append(ID_DELIM); |
409 | } |
410 | for (int32_t i=0; i<count; ++i) { |
411 | UnicodeString rule; |
412 | |
413 | |
414 | |
415 | |
416 | |
417 | if (trans[i]->getID().startsWith(PASS_STRING, 5)) { |
418 | trans[i]->toRules(rule, escapeUnprintable); |
419 | if (numAnonymousRBTs > 1 && i > 0 && trans[i - 1]->getID().startsWith(PASS_STRING, 5)) |
420 | rule = UNICODE_STRING_SIMPLE("::Null;") + rule; |
421 | |
422 | |
423 | |
424 | |
425 | |
426 | } else if (trans[i]->getID().indexOf(ID_DELIM) >= 0) { |
427 | trans[i]->toRules(rule, escapeUnprintable); |
428 | |
429 | |
430 | } else { |
431 | trans[i]->Transliterator::toRules(rule, escapeUnprintable); |
432 | } |
433 | _smartAppend(rulesSource, NEWLINE); |
434 | rulesSource.append(rule); |
435 | _smartAppend(rulesSource, ID_DELIM); |
436 | } |
437 | return rulesSource; |
438 | } |
439 | |
440 | |
441 | |
442 | |
443 | void CompoundTransliterator::handleGetSourceSet(UnicodeSet& result) const { |
444 | UnicodeSet set; |
445 | result.clear(); |
446 | for (int32_t i=0; i<count; ++i) { |
447 | result.addAll(trans[i]->getSourceSet(set)); |
448 | |
449 | |
450 | |
451 | |
452 | |
453 | |
454 | |
455 | |
456 | if (!result.isEmpty()) { |
457 | break; |
458 | } |
459 | } |
460 | } |
461 | |
462 | |
463 | |
464 | |
465 | UnicodeSet& CompoundTransliterator::getTargetSet(UnicodeSet& result) const { |
466 | UnicodeSet set; |
467 | result.clear(); |
468 | for (int32_t i=0; i<count; ++i) { |
469 | |
470 | result.addAll(trans[i]->getTargetSet(set)); |
471 | } |
472 | return result; |
473 | } |
474 | |
475 | |
476 | |
477 | |
478 | void CompoundTransliterator::handleTransliterate(Replaceable& text, UTransPosition& index, |
479 | UBool incremental) const { |
480 | |
481 | |
482 | |
483 | |
484 | |
485 | |
486 | |
487 | |
488 | |
489 | |
490 | |
491 | |
492 | |
493 | |
494 | |
495 | |
496 | |
497 | |
498 | |
499 | |
500 | |
501 | |
502 | |
503 | |
504 | |
505 | |
506 | |
507 | |
508 | |
509 | |
510 | |
511 | |
512 | |
513 | |
514 | |
515 | |
516 | |
517 | |
518 | |
519 | |
520 | |
521 | |
522 | |
523 | |
524 | |
525 | |
526 | |
527 | |
528 | |
529 | |
530 | |
531 | |
532 | |
533 | |
534 | |
535 | if (count < 1) { |
536 | index.start = index.limit; |
537 | return; |
538 | } |
539 | |
540 | |
541 | |
542 | |
543 | |
544 | int32_t compoundLimit = index.limit; |
545 | |
546 | |
547 | |
548 | int32_t compoundStart = index.start; |
549 | |
550 | int32_t delta = 0; |
551 | |
552 | |
553 | |
554 | for (int32_t i=0; i<count; ++i) { |
555 | index.start = compoundStart; |
556 | int32_t limit = index.limit; |
557 | |
558 | if (index.start == index.limit) { |
559 | |
560 | break; |
561 | } |
562 | |
563 | trans[i]->filteredTransliterate(text, index, incremental); |
564 | |
565 | |
566 | |
567 | |
568 | |
569 | |
570 | |
571 | |
572 | if (!incremental && index.start != index.limit) { |
573 | |
574 | index.start = index.limit; |
575 | } |
576 | |
577 | |
578 | delta += index.limit - limit; |
579 | |
580 | if (incremental) { |
581 | |
582 | |
583 | |
584 | |
585 | |
586 | index.limit = index.start; |
587 | } |
588 | } |
589 | |
590 | compoundLimit += delta; |
591 | |
592 | |
593 | |
594 | |
595 | index.limit = compoundLimit; |
596 | } |
597 | |
598 | |
599 | |
600 | |
601 | |
602 | void CompoundTransliterator::computeMaximumContextLength(void) { |
603 | int32_t max = 0; |
604 | for (int32_t i=0; i<count; ++i) { |
| |
| 13 | | Loop condition is true. Entering loop body | |
|
605 | int32_t len = trans[i]->getMaximumContextLength(); |
| 14 | | Called C++ object pointer is null |
|
606 | if (len > max) { |
607 | max = len; |
608 | } |
609 | } |
610 | setMaximumContextLength(max); |
611 | } |
612 | |
613 | U_NAMESPACE_END |
614 | |
615 | #endif /* #if !UCONFIG_NO_TRANSLITERATION */ |
616 | |
617 | |