Bug Summary

File:libraries/libdxfrw/src/intern/rscodec.cpp
Warning:line 143, column 42
The left operand of '+' is a garbage value due to array index out of bounds

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name rscodec.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 -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 -fdebug-compilation-dir=/home/runner/work/LibreCAD/LibreCAD/libraries/libdxfrw -fcoverage-compilation-dir=/home/runner/work/LibreCAD/LibreCAD/libraries/libdxfrw -resource-dir /usr/lib/llvm-18/lib/clang/18 -D _REENTRANT -D MUPARSER_STATIC -D QT_NO_DEBUG -I . -I ../../../Qt/6.9.0/gcc_64/mkspecs/linux-g++ -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -std=gnu++1z -fdeprecated-macro -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fcxx-exceptions -fexceptions -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/runner/work/LibreCAD/LibreCAD/out/2026-08-04-154929-5069-1 -x c++ src/intern/rscodec.cpp
1/******************************************************************************
2** libDXFrw - Library to read/write DXF files (ascii & binary) **
3** **
4** Copyright (C) 2011-2014 J.F. Soriano (Rallaz), rallazz@gmail.com **
5** **
6** This library is free software, licensed under the terms of the GNU **
7** General Public License as published by the Free Software Foundation, **
8** either version 2 of the License, or (at your option) any later version. **
9** You should have received a copy of the GNU General Public License **
10** along with this program. If not, see <http://www.gnu.org/licenses/>. **
11******************************************************************************/
12
13/**
14 * Reed-Solomon codec
15 * Reed Solomon code lifted from encoder/decoder for Reed-Solomon written by Simon Rockliff
16 *
17 * Original code:
18 * This program may be freely modified and/or given to whoever wants it.
19 * A condition of such distribution is that the author's contribution be
20 * acknowledged by his name being left in the comments heading the program,
21 * however no responsibility is accepted for any financial or other loss which
22 * may result from some unforseen errors or malfunctioning of the program
23 * during use.
24 * Simon Rockliff, 26th June 1991
25 */
26
27
28#include "rscodec.h"
29#include <new> // std::nothrow
30#include <fstream>
31
32RScodec::RScodec(unsigned int pp, int mm, int tt) {
33 this->mm = mm;
34 this->tt = tt;
35 nn = (1<<mm) -1; //mm==8 nn=255
1
Assuming right operand of bit shift is non-negative but less than 32
36 kk = nn -(tt*2);
37 isOk = true;
38
39 alpha_to = new (std::nothrow) int[nn+1];
40 index_of = new (std::nothrow) unsigned int[nn+1];
2
Storing uninitialized value
41 gg = new (std::nothrow) int[nn-kk+1];
42
43 RSgenerate_gf(pp) ;
44 /* compute the generator polynomial for this RS code */
45 RSgen_poly() ;
3
Calling 'RScodec::RSgen_poly'
46
47 // decode() scratch buffers -- see the member declarations in rscodec.h.
48 const int bb = nn - kk;
49 recd = new (std::nothrow) int[nn];
50 elp = new int*[bb + 2];
51 for (int i = 0; i < bb + 2; ++i) {
52 elp[i] = new int[bb];
53 }
54 d = new int[bb + 2];
55 l = new int[bb + 2];
56 u_lu = new int[bb + 2];
57 s = new int[bb + 1];
58 root = new int[tt];
59 loc = new int[tt];
60 z = new int[tt + 1];
61 err = new int[nn];
62 reg = new int[tt + 1];
63}
64
65RScodec::~RScodec() {
66 delete[] alpha_to;
67 delete[] index_of;
68 delete[] gg;
69
70 delete[] recd;
71 for (int i = 0; i < nn - kk + 2; ++i) {
72 delete[] elp[i];
73 }
74 delete[] elp;
75 delete[] d;
76 delete[] l;
77 delete[] u_lu;
78 delete[] s;
79 delete[] root;
80 delete[] loc;
81 delete[] z;
82 delete[] err;
83 delete[] reg;
84}
85
86
87/* generate GF(2^mm) from the irreducible polynomial p(X) in pp[0]..pp[mm]
88 lookup tables: index->polynomial form alpha_to[] contains j=alpha**i;
89 polynomial form -> index form index_of[j=alpha**i] = i
90 alpha=2 is the primitive element of GF(2^mm)
91*/
92void RScodec::RSgenerate_gf(unsigned int pp) const {
93 int i, mask ;
94 int pb;
95
96 mask = 1 ;
97 alpha_to[mm] = 0 ;
98 for (i=0; i<mm; i++) {
99 alpha_to[i] = mask ;
100 index_of[alpha_to[i]] = i ;
101 pb = (pp >>(mm-1-i)) & 1;
102 if (pb!=0) {
103 alpha_to[mm] ^= mask;
104 }
105 mask <<= 1 ;
106 }
107 index_of[alpha_to[mm]] = mm ;
108 mask >>= 1 ;
109 for (i=mm+1; i<nn; i++) {
110 if (alpha_to[i-1] >= mask) {
111 alpha_to[i] = alpha_to[mm] ^ ((alpha_to[i-1]^mask)<<1) ;
112 } else {
113 alpha_to[i] = alpha_to[i-1]<<1 ;
114 }
115 index_of[alpha_to[i]] = i ;
116 }
117 index_of[0] = -1 ;
118}
119
120
121/* Obtain the generator polynomial of the tt-error correcting, length
122 nn=(2^mm -1) Reed Solomon code from the product of (X+alpha**i), i=1..2*tt
123*/
124void RScodec::RSgen_poly() {
125 int i,j ;
126 int tmp;
127 int bb = nn-kk; //nn-kk length of parity data
128
129 gg[0] = 2 ; /* primitive element alpha = 2 for GF(2**mm) */
4
Assigning 2
130 gg[1] = 1 ; /* g(x) = (X+alpha) initially */
131 for (i=2; i<=bb; i++) {
5
Assuming 'i' is <= 'bb'
6
Loop condition is true. Entering loop body
132 gg[i] = 1 ;
133 for (j=i-1; j>0; j--) {
7
Loop condition is true. Entering loop body
10
Loop condition is false. Execution continues on line 143
134 if (gg[j] != 0) {
135 if (gg[j]<0 || gg[j]>nn) { isOk=false; return; } // bound both ends of index_of[]
8
Taking false branch
136 tmp = (index_of[gg[j]]+i)%nn;
137 if (tmp
8.1
'tmp' is >= 0
<0) { isOk=false; return; }
9
Taking false branch
138 gg[j] = gg[j-1]^ alpha_to[tmp] ;
139 } else {
140 gg[j] = gg[j-1] ;
141 }
142 }
143 gg[0] = alpha_to[(index_of[gg[0]]+i)%nn] ; /* gg[0] can never be zero */
11
The left operand of '+' is a garbage value due to array index out of bounds
144 }
145 /* convert gg[] to index form for quicker encoding */
146 for (i=0; i<=bb; i++) {
147 gg[i] = index_of[gg[i]] ;
148 }
149}
150
151int RScodec::calcDecode(unsigned char* data, int* recd, int** elp, int* d, int* l, int* u_lu, int* s, int* root, int* loc, int* z, int* err, int* reg, int bb) const {
152 if (!isOk) {
153 return -1;
154 }
155 int count = 0;
156 int syn_error = 0;
157 int i, j, u, q;
158
159 // for (int i=0; i<nn; i++)
160 // recd[i] = index_of[recd[i]] ; /* put recd[i] into index form */
161 for (int i = 0, j = bb; i<kk; i++, j++) {
162 recd[j] = index_of[data[j]]; /* put data in recd[i] into index form */
163 }
164 for (int i = kk, j = 0; i<nn; i++, j++) {
165 recd[j] = index_of[data[j]]; /* put data in recd[i] into index form */
166 }
167
168 /* first form the syndromes */
169 for (i = 1; i <= bb; i++) {
170 s[i] = 0;
171 for (j = 0; j<nn; j++) {
172 if (recd[j] != -1) {
173 s[i] ^= alpha_to[(recd[j] + i*j) % nn]; /* recd[j] in index form */
174 }
175 }
176 /* convert syndrome from polynomial form to index form */
177 if (s[i] != 0) {
178 syn_error = 1; /* set flag if non-zero syndrome => error */
179 }
180 s[i] = index_of[s[i]];
181 }
182
183 if (!syn_error) { /* if no errors, ends */
184 /* no non-zero syndromes => no errors: output is received codeword */
185 return 0;
186 }
187
188 /* errors are present, try and correct */
189 /* compute the error location polynomial via the Berlekamp iterative algorithm,
190 following the terminology of Lin and Costello : d[u] is the 'mu'th
191 discrepancy, where u='mu'+1 and 'mu' (the Greek letter!) is the step number
192 ranging from -1 to 2*tt (see L&C), l[u] is the
193 degree of the elp at that step, and u_l[u] is the difference between the
194 step number and the degree of the elp.
195 */
196 /* initialise table entries */
197 d[0] = 0; /* index form */
198 d[1] = s[1]; /* index form */
199 elp[0][0] = 0; /* index form */
200 elp[1][0] = 1; /* polynomial form */
201 for (i = 1; i<bb; i++) {
202 elp[0][i] = -1; /* index form */
203 elp[1][i] = 0; /* polynomial form */
204 }
205 l[0] = 0;
206 l[1] = 0;
207 u_lu[0] = -1;
208 u_lu[1] = 0;
209 u = 0;
210
211 do {
212 u++;
213 if (d[u] == -1) {
214 l[u + 1] = l[u];
215 for (i = 0; i <= l[u]; i++) {
216 elp[u + 1][i] = elp[u][i];
217 elp[u][i] = index_of[elp[u][i]];
218 }
219 }
220 else {
221 /* search for words with greatest u_lu[q] for which d[q]!=0 */
222 q = u - 1;
223 while ((d[q] == -1) && (q>0)) {
224 q--;
225 }
226 /* have found first non-zero d[q] */
227 if (q>0) {
228 j = q;
229 do {
230 j--;
231 if ((d[j] != -1) && (u_lu[q]<u_lu[j])) {
232 q = j;
233 }
234 } while (j>0);
235 }
236
237 /* have now found q such that d[u]!=0 and u_lu[q] is maximum */
238 /* store degree of new elp polynomial */
239 if (l[u]>l[q] + u - q) {
240 l[u + 1] = l[u];
241 }
242 else {
243 l[u + 1] = l[q] + u - q;
244 }
245
246 /* form new elp(x) */
247 for (i = 0; i<bb; i++) {
248 elp[u + 1][i] = 0;
249 }
250 for (i = 0; i <= l[q]; i++){
251 if (elp[q][i] != -1) {
252 elp[u + 1][i + u - q] = alpha_to[(d[u] + nn - d[q] + elp[q][i]) % nn];
253 }
254 }
255 for (i = 0; i <= l[u]; i++) {
256 elp[u + 1][i] ^= elp[u][i];
257 elp[u][i] = index_of[elp[u][i]]; /*convert old elp value to index*/
258 }
259 }
260 u_lu[u + 1] = u - l[u + 1];
261
262 /* form (u+1)th discrepancy */
263 if (u<bb){ /* no discrepancy computed on last iteration */
264 if (s[u + 1] != -1) {
265 d[u + 1] = alpha_to[s[u + 1]];
266 }
267 else {
268 d[u + 1] = 0;
269 }
270 for (i = 1; i <= l[u + 1]; i++){
271 if ((s[u + 1 - i] != -1) && (elp[u + 1][i] != 0)) {
272 d[u + 1] ^= alpha_to[(s[u + 1 - i] + index_of[elp[u + 1][i]]) % nn];
273 }
274 }
275 d[u + 1] = index_of[d[u + 1]]; /* put d[u+1] into index form */
276 }
277 } while ((u<bb) && (l[u + 1] <= tt));
278
279 u++;
280 if (l[u]>tt) { /* elp has degree has degree >tt hence cannot solve */
281 return -1; /* just output is received codeword as is */
282 }
283
284 /* can correct error */
285 /* put elp into index form */
286 for (i = 0; i <= l[u]; i++) {
287 elp[u][i] = index_of[elp[u][i]];
288 }
289
290 /* find roots of the error location polynomial */
291 for (i = 1; i <= l[u]; i++) {
292 reg[i] = elp[u][i];
293 }
294 count = 0;
295 for (i = 1; i <= nn; i++) {
296 q = 1;
297 for (j = 1; j <= l[u]; j++) {
298 if (reg[j] != -1) {
299 reg[j] = (reg[j] + j) % nn;
300 q ^= alpha_to[reg[j]];
301 }
302 }
303 if (!q) { /* store root and error location number indices */
304 root[count] = i;
305 loc[count] = nn - i;
306 count++;
307 }
308 }
309
310 if (count != l[u]) { /* no. roots != degree of elp => >tt errors and cannot solve */
311 return -1; /* just output is received codeword as is */
312 }
313
314 /* no. roots = degree of elp hence <= tt errors */
315 /* form polynomial z(x) */
316 for (i = 1; i <= l[u]; i++) { /* Z[0] = 1 always - do not need */
317 if ((s[i] != -1) && (elp[u][i] != -1)) {
318 z[i] = alpha_to[s[i]] ^ alpha_to[elp[u][i]];
319 }
320 else if ((s[i] != -1) && (elp[u][i] == -1)) {
321 z[i] = alpha_to[s[i]];
322 }
323 else if ((s[i] == -1) && (elp[u][i] != -1)) {
324 z[i] = alpha_to[elp[u][i]];
325 }
326 else {
327 z[i] = 0;
328 }
329 for (j = 1; j<i; j++) {
330 if ((s[j] != -1) && (elp[u][i - j] != -1)) {
331 z[i] ^= alpha_to[(elp[u][i - j] + s[j]) % nn];
332 }
333 }
334 z[i] = index_of[z[i]]; /* put into index form */
335 }
336
337 /* evaluate errors at locations given by error location numbers loc[i] */
338 for (i = 0; i<nn; i++) {
339 err[i] = 0;
340 }
341 for (i = 0; i<l[u]; i++) { /* compute numerator of error term first */
342 err[loc[i]] = 1; /* accounts for z[0] */
343 for (j = 1; j <= l[u]; j++) {
344 if (z[j] != -1) {
345 err[loc[i]] ^= alpha_to[(z[j] + j*root[i]) % nn];
346 }
347 }
348 if (err[loc[i]] != 0) {
349 err[loc[i]] = index_of[err[loc[i]]];
350 q = 0; /* form denominator of error term */
351 for (j = 0; j<l[u]; j++) {
352 if (j != i) {
353 q += index_of[1 ^ alpha_to[(loc[j] + root[i]) % nn]];
354 }
355 }
356 q = q % nn;
357 err[loc[i]] = alpha_to[(err[loc[i]] - q + nn) % nn];
358 data[loc[i]] ^= err[loc[i]]; /*change errors by correct data, in polynomial form */
359 }
360 }
361 return count;
362}
363
364/** take the string of symbols in data[i], i=0..(k-1) and encode systematically
365 to produce 2*tt parity symbols in bd[0]..bd[2*tt-1]
366 data[] is input and bd[] is output in polynomial form.
367 Encoding is done by using a feedback shift register with appropriate
368 connections specified by the elements of gg[], which was generated above.
369 Codeword is c(X) = data(X)*X**(nn-kk)+ b(X) */
370bool RScodec::encode(unsigned char *data, unsigned char *parity) const {
371 if (!isOk) {
372 return false;
373 }
374 int i,j ;
375 int feedback ;
376 unsigned char *idata = data;
377 unsigned char *bd = parity;
378 int bb = nn-kk; //nn-kk length of parity data
379
380 for (i=0; i<bb; i++) {
381 bd[i] = 0 ;
382 }
383 for (i=kk-1; i>=0; i--) {
384 feedback = index_of[idata[i]^bd[bb-1]] ;
385 if (feedback != -1) {
386 for (j=bb-1; j>0; j--) {
387 if (gg[j] != -1) {
388 bd[j] = bd[j-1]^alpha_to[(gg[j]+feedback)%nn] ;
389 }
390 else {
391 bd[j] = bd[j-1] ;
392 }
393 }
394 bd[0] = alpha_to[(gg[0]+feedback)%nn] ;
395 } else {
396 for (j=bb-1; j>0; j--) {
397 bd[j] = bd[j-1] ;
398 }
399 bd[0] = 0 ;
400 }
401 }
402 return true;
403}
404
405
406/* assume we have received bits grouped into mm-bit symbols in recd[i],
407 i=0..(nn-1), and recd[i] is index form (ie as powers of alpha).
408 We first compute the 2*tt syndromes by substituting alpha**i into rec(X) and
409 evaluating, storing the syndromes in s[i], i=1..2tt (leave s[0] zero) .
410 Then we use the Berlekamp iteration to find the error location polynomial
411 elp[i]. If the degree of the elp is >tt, we cannot correct all the errors
412 and hence just put out the information symbols uncorrected. If the degree of
413 elp is <=tt, we substitute alpha**i , i=1..n into the elp to get the roots,
414 hence the inverse roots, the error location numbers. If the number of errors
415 located does not equal the degree of the elp, we have more than tt errors
416 and cannot correct them. Otherwise, we then solve for the error value at
417 the error location and correct the error. The procedure is that found in
418 Lin and Costello. For the cases where the number of errors is known to be too
419 large to correct, the information symbols as received are output (the
420 advantage of systematic encoding is that hopefully some of the information
421 symbols will be okay and that if we are in luck, the errors are in the
422 parity part of the transmitted codeword). Of course, these insoluble cases
423 can be returned as error flags to the calling routine if desired. */
424/** return value: number of corrected errors or -1 if can't correct it */
425int RScodec::decode(unsigned char *data) {
426 if (!isOk) {
427 return -1;
428 }
429 const int bb = nn-kk; //nn-kk length of parity data
430
431 // Scratch buffers are member-owned (sized once in the constructor) and
432 // reused across every call -- see the member declarations in rscodec.h.
433 return calcDecode(data, recd, elp, d, l, u_lu, s, root, loc, z, err, reg, bb);
434}