Bug Summary

File:bidi.c
Warning:line 65, column 12
Although the value stored to 'bc' is used in the enclosing expression, the value is never actually read from 'bc'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name bidi.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -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 -fhalf-no-semantic-interposition -mframe-pointer=none -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=/builds/libidn/libidn2/lib -resource-dir /usr/bin/../lib/clang/17 -D HAVE_CONFIG_H -I . -I .. -D IDN2_BUILDING -D SRCDIR="." -I ../gl -I ../gl -I ../unistring/ -I ../unistring/ -D PIC -internal-isystem /usr/bin/../lib/clang/17/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/13/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wwrite-strings -Wno-analyzer-malloc-leak -Wno-sign-compare -Wno-system-headers -fconst-strings -fdebug-compilation-dir=/builds/libidn/libidn2/lib -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/libidn/libidn2/clang-analyzer/2025-05-14-230017-16945-1 -x c bidi.c
1/* bidi.c - IDNA right to left checking functions
2 Copyright (C) 2011-2025 Simon Josefsson
3
4 Libidn2 is free software: you can redistribute it and/or modify it
5 under the terms of either:
6
7 * the GNU Lesser General Public License as published by the Free
8 Software Foundation; either version 3 of the License, or (at
9 your option) any later version.
10
11 or
12
13 * the GNU General Public License as published by the Free
14 Software Foundation; either version 2 of the License, or (at
15 your option) any later version.
16
17 or both in parallel, as here.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 You should have received copies of the GNU General Public License and
25 the GNU Lesser General Public License along with this program. If
26 not, see <http://www.gnu.org/licenses/>.
27*/
28
29#include <config.h>
30
31#include "idn2.h"
32
33#include <sys/types.h>
34#include <stdbool.h>
35
36#include "bidi.h"
37
38#include <unictype.h>
39
40static bool_Bool
41_isBidi (const uint32_t *label, size_t llen)
42{
43 for (; (ssize_t) llen > 0; llen--)
44 {
45 int bc = uc_bidi_category (*label++);
46
47 if (bc == UC_BIDI_R || bc == UC_BIDI_AL || bc == UC_BIDI_AN)
48 return 1;
49 }
50
51 return 0;
52}
53
54/* IDNA2008 BIDI check (RFC 5893) */
55int
56_idn2_bidi (const uint32_t *label, size_t llen)
57{
58 int bc;
59 int endok = 1;
60
61 if (!_isBidi (label, llen))
62 return IDN2_OK;
63
64 // 2.1
65 switch ((bc = uc_bidi_category (*label)))
Although the value stored to 'bc' is used in the enclosing expression, the value is never actually read from 'bc'
66 {
67 case UC_BIDI_L:
68 // check 2.5 & 2.6
69 for (size_t it = 1; it < llen; it++)
70 {
71 bc = uc_bidi_category (label[it]);
72
73 if (bc == UC_BIDI_L || bc == UC_BIDI_EN || bc == UC_BIDI_NSM)
74 {
75 endok = 1;
76 }
77 else
78 {
79 if (bc != UC_BIDI_ES && bc != UC_BIDI_CS && bc != UC_BIDI_ET
80 && bc != UC_BIDI_ON && bc != UC_BIDI_BN)
81 {
82 /* printf("LTR label contains invalid code point\n"); */
83 return IDN2_BIDI;
84 }
85 endok = 0;
86 }
87 }
88 /* printf("LTR label ends with invalid code point\n"); */
89 return endok ? IDN2_OK : IDN2_BIDI;
90
91 case UC_BIDI_R:
92 case UC_BIDI_AL:
93 // check 2.2, 2.3, 2.4
94 /* printf("Label[0]=%04X: %s\n", label[0], uc_bidi_category_name(bc)); */
95 for (size_t it = 1; it < llen; it++)
96 {
97 bc = uc_bidi_category (label[it]);
98
99 /* printf("Label[%d]=%04X: %s\n", (int) it, label[it], uc_bidi_category_name(bc)); */
100 if (bc == UC_BIDI_R || bc == UC_BIDI_AL || bc == UC_BIDI_EN
101 || bc == UC_BIDI_AN || bc == UC_BIDI_NSM)
102 {
103 endok = 1;
104 }
105 else
106 {
107 if (bc != UC_BIDI_ES && bc != UC_BIDI_CS && bc != UC_BIDI_ET
108 && bc != UC_BIDI_ON && bc != UC_BIDI_BN)
109 {
110 /* printf("RTL label contains invalid code point\n"); */
111 return IDN2_BIDI;
112 }
113 endok = 0;
114 }
115 }
116 /* printf("RTL label ends with invalid code point\n"); */
117 return endok ? IDN2_OK : IDN2_BIDI;
118
119 default:
120 /* printf("Label begins with invalid BIDI class %s\n", uc_bidi_category_name(bc)); */
121 return IDN2_BIDI;
122 }
123}