• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • text
kcodecs.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2000-2001 Dawit Alemayehu <adawit@kde.org>
3 Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License (LGPL)
7 version 2 as published by the Free Software Foundation.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 RFC 1321 "MD5 Message-Digest Algorithm" Copyright (C) 1991-1992. // krazy:exclude=copyright
19 RSA Data Security, Inc. Created 1991. All rights reserved.
20
21 The KMD5 class is based on a C++ implementation of
22 "RSA Data Security, Inc. MD5 Message-Digest Algorithm" by
23 Mordechai T. Abzug, Copyright (c) 1995. This implementation // krazy:exclude=copyright
24 passes the test-suite as defined in RFC 1321.
25
26 The encoding and decoding utilities in KCodecs with the exception of
27 quoted-printable are based on the java implementation in HTTPClient
28 package by Ronald Tschalär Copyright (C) 1996-1999. // krazy:exclude=copyright
29
30 The quoted-printable codec as described in RFC 2045, section 6.7. is by
31 Rik Hemsley (C) 2001.
32*/
33
34#include "kcodecs.h"
35
36#include <stdio.h>
37#include <string.h>
38#include <stdlib.h>
39
40#include <kdebug.h>
41#include <QtCore/QIODevice>
42#include <QtCore/QTextCodec>
43
44#define KMD5_S11 7
45#define KMD5_S12 12
46#define KMD5_S13 17
47#define KMD5_S14 22
48#define KMD5_S21 5
49#define KMD5_S22 9
50#define KMD5_S23 14
51#define KMD5_S24 20
52#define KMD5_S31 4
53#define KMD5_S32 11
54#define KMD5_S33 16
55#define KMD5_S34 23
56#define KMD5_S41 6
57#define KMD5_S42 10
58#define KMD5_S43 15
59#define KMD5_S44 21
60
61namespace KCodecs
62{
63
64static const char Base64EncMap[64] =
65{
66 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
67 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50,
68 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
69 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
70 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E,
71 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76,
72 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33,
73 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F
74};
75
76static const char Base64DecMap[128] =
77{
78 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
81 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
82 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
83 0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x3F,
84 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B,
85 0x3C, 0x3D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
87 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
88 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
89 0x17, 0x18, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
91 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
92 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
93 0x31, 0x32, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00
94};
95
96static const char UUEncMap[64] =
97{
98 0x60, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
99 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
100 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
101 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
102 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
103 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
104 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
105 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
106};
107
108static const char UUDecMap[128] =
109{
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
115 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
116 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
117 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
118 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
119 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
120 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
121 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
122 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
123 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
126};
127
128static const char hexChars[16] =
129{
130 '0', '1', '2', '3', '4', '5', '6', '7',
131 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
132};
133
134static const unsigned int maxQPLineLength = 70;
135
136} // namespace KCodecs
137
138
139/******************************** KCodecs ********************************/
140// strchr(3) for broken systems.
141static int rikFindChar(register const char * _s, const char c)
142{
143 register const char * s = _s;
144
145 while (true)
146 {
147 if ((0 == *s) || (c == *s)) break; ++s;
148 if ((0 == *s) || (c == *s)) break; ++s;
149 if ((0 == *s) || (c == *s)) break; ++s;
150 if ((0 == *s) || (c == *s)) break; ++s;
151 }
152
153 return s - _s;
154}
155
156QByteArray KCodecs::quotedPrintableEncode(const QByteArray& in, bool useCRLF)
157{
158 QByteArray out;
159 quotedPrintableEncode (in, out, useCRLF);
160 return out;
161}
162
163void KCodecs::quotedPrintableEncode(const QByteArray& in, QByteArray& out, bool useCRLF)
164{
165 out.resize (0);
166 if (in.isEmpty())
167 return;
168
169 char *cursor;
170 const char *data;
171 unsigned int lineLength;
172 unsigned int pos;
173
174 const unsigned int length = in.size();
175 const unsigned int end = length - 1;
176
177
178 // Reasonable guess for output size when we're encoding
179 // mostly-ASCII data. It doesn't really matter, because
180 // the underlying allocation routines are quite efficient,
181 // but it's nice to have 0 allocations in many cases.
182 out.resize ((length*12)/10);
183 cursor = out.data();
184 data = in.data();
185 lineLength = 0;
186 pos = 0;
187
188 for (unsigned int i = 0; i < length; i++)
189 {
190 unsigned char c (data[i]);
191
192 // check if we have to enlarge the output buffer, use
193 // a safety margin of 16 byte
194 pos = cursor-out.data();
195 if (out.size()-pos < 16) {
196 out.resize(out.size()+4096);
197 cursor = out.data()+pos;
198 }
199
200 // Plain ASCII chars just go straight out.
201
202 if ((c >= 33) && (c <= 126) && ('=' != c))
203 {
204 *cursor++ = c;
205 ++lineLength;
206 }
207
208 // Spaces need some thought. We have to encode them at eol (or eof).
209
210 else if (' ' == c)
211 {
212 if
213 (
214 (i >= length)
215 ||
216 ((i < end) && ((useCRLF && ('\r' == data[i + 1]) && ('\n' == data[i + 2]))
217 ||
218 (!useCRLF && ('\n' == data[i + 1]))))
219 )
220 {
221 *cursor++ = '=';
222 *cursor++ = '2';
223 *cursor++ = '0';
224
225 lineLength += 3;
226 }
227 else
228 {
229 *cursor++ = ' ';
230 ++lineLength;
231 }
232 }
233 // If we find a line break, just let it through.
234 else if ((useCRLF && ('\r' == c) && (i < end) && ('\n' == data[i + 1])) ||
235 (!useCRLF && ('\n' == c)))
236 {
237 lineLength = 0;
238
239 if (useCRLF) {
240 *cursor++ = '\r';
241 *cursor++ = '\n';
242 ++i;
243 } else {
244 *cursor++ = '\n';
245 }
246 }
247
248 // Anything else is converted to =XX.
249
250 else
251 {
252 *cursor++ = '=';
253 *cursor++ = hexChars[c / 16];
254 *cursor++ = hexChars[c % 16];
255
256 lineLength += 3;
257 }
258
259 // If we're approaching the maximum line length, do a soft line break.
260
261 if ((lineLength > maxQPLineLength) && (i < end))
262 {
263 if (useCRLF) {
264 *cursor++ = '=';
265 *cursor++ = '\r';
266 *cursor++ = '\n';
267 } else {
268 *cursor++ = '=';
269 *cursor++ = '\n';
270 }
271
272 lineLength = 0;
273 }
274 }
275
276 out.truncate(cursor - out.data());
277}
278
279QByteArray KCodecs::quotedPrintableDecode(const QByteArray & in)
280{
281 QByteArray out;
282 quotedPrintableDecode (in, out);
283 return out;
284}
285
286
287void KCodecs::quotedPrintableDecode(const QByteArray& in, QByteArray& out)
288{
289 // clear out the output buffer
290 out.resize (0);
291 if (in.isEmpty())
292 return;
293
294 char *cursor;
295 const char *data;
296 const unsigned int length = in.size();
297
298 data = in.data();
299 out.resize (length);
300 cursor = out.data();
301
302 for (unsigned int i = 0; i < length; i++)
303 {
304 char c(in[i]);
305
306 if ('=' == c)
307 {
308 if (i < length - 2)
309 {
310 char c1 = in[i + 1];
311 char c2 = in[i + 2];
312
313 if (('\n' == c1) || ('\r' == c1 && '\n' == c2))
314 {
315 // Soft line break. No output.
316 if ('\r' == c1)
317 i += 2; // CRLF line breaks
318 else
319 i += 1;
320 }
321 else
322 {
323 // =XX encoded byte.
324
325 int hexChar0 = rikFindChar(hexChars, c1);
326 int hexChar1 = rikFindChar(hexChars, c2);
327
328 if (hexChar0 < 16 && hexChar1 < 16)
329 {
330 *cursor++ = char((hexChar0 * 16) | hexChar1);
331 i += 2;
332 }
333 }
334 }
335 }
336 else
337 {
338 *cursor++ = c;
339 }
340 }
341
342 out.truncate(cursor - out.data());
343}
344
345QByteArray KCodecs::base64Encode( const QByteArray& in, bool insertLFs )
346{
347 QByteArray out;
348 base64Encode( in, out, insertLFs );
349 return out;
350}
351
352void KCodecs::base64Encode( const QByteArray& in, QByteArray& out,
353 bool insertLFs )
354{
355 // clear out the output buffer
356 out.resize (0);
357 if ( in.isEmpty() )
358 return;
359
360 unsigned int sidx = 0;
361 int didx = 0;
362 const char* data = in.data();
363 const unsigned int len = in.size();
364
365 unsigned int out_len = ((len+2)/3)*4;
366
367 // Deal with the 76 characters or less per
368 // line limit specified in RFC 2045 on a
369 // pre request basis.
370 insertLFs = (insertLFs && out_len > 76);
371 if ( insertLFs )
372 out_len += ((out_len-1)/76);
373
374 int count = 0;
375 out.resize( out_len );
376
377 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
378 if ( len > 1 )
379 {
380 while (sidx < len-2)
381 {
382 if ( insertLFs )
383 {
384 if ( count && (count%76) == 0 )
385 out[didx++] = '\n';
386 count += 4;
387 }
388 out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
389 out[didx++] = Base64EncMap[((data[sidx+1] >> 4) & 017) |
390 ((data[sidx] << 4) & 077)];
391 out[didx++] = Base64EncMap[((data[sidx+2] >> 6) & 003) |
392 ((data[sidx+1] << 2) & 077)];
393 out[didx++] = Base64EncMap[data[sidx+2] & 077];
394 sidx += 3;
395 }
396 }
397
398 if (sidx < len)
399 {
400 if ( insertLFs && (count > 0) && (count%76) == 0 )
401 out[didx++] = '\n';
402
403 out[didx++] = Base64EncMap[(data[sidx] >> 2) & 077];
404 if (sidx < len-1)
405 {
406 out[didx++] = Base64EncMap[((data[sidx+1] >> 4) & 017) |
407 ((data[sidx] << 4) & 077)];
408 out[didx++] = Base64EncMap[(data[sidx+1] << 2) & 077];
409 }
410 else
411 {
412 out[didx++] = Base64EncMap[(data[sidx] << 4) & 077];
413 }
414 }
415
416 // Add padding
417 while (didx < out.size())
418 {
419 out[didx] = '=';
420 didx++;
421 }
422}
423
424QByteArray KCodecs::base64Decode( const QByteArray& in )
425{
426 QByteArray out;
427 base64Decode( in, out );
428 return out;
429}
430
431void KCodecs::base64Decode( const QByteArray& in, QByteArray& out )
432{
433 out.resize(0);
434 if ( in.isEmpty() )
435 return;
436
437 int count = 0;
438 int len = in.size(), tail = len;
439 const char* data = in.data();
440
441 // Deal with possible *nix "BEGIN" marker!!
442 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
443 data[count] == '\t' || data[count] == ' ') )
444 count++;
445
446 if ( strncasecmp(data+count, "begin", 5) == 0 )
447 {
448 count += 5;
449 while ( count < len && data[count] != '\n' && data[count] != '\r' )
450 count++;
451
452 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
453 count ++;
454
455 data += count;
456 tail = (len -= count);
457 }
458
459 // Find the tail end of the actual encoded data even if
460 // there is/are trailing CR and/or LF.
461 while ( data[tail-1] == '=' || data[tail-1] == '\n' ||
462 data[tail-1] == '\r' )
463 if ( data[--tail] != '=' ) len = tail;
464
465 unsigned int outIdx = 0;
466 out.resize( (count=len) );
467 for (int idx = 0; idx < count; idx++)
468 {
469 // Adhere to RFC 2045 and ignore characters
470 // that are not part of the encoding table.
471 unsigned char ch = data[idx];
472 if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) ||
473 (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
474 {
475 out[outIdx++] = Base64DecMap[ch];
476 }
477 else
478 {
479 len--;
480 tail--;
481 }
482 }
483
484 // kDebug() << "Tail size = " << tail << ", Length size = " << len;
485
486 // 4-byte to 3-byte conversion
487 len = (tail>(len/4)) ? tail-(len/4) : 0;
488 int sidx = 0, didx = 0;
489 if ( len > 1 )
490 {
491 while (didx < len-2)
492 {
493 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
494 out[didx+1] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
495 out[didx+2] = (((out[sidx+2] << 6) & 255) | (out[sidx+3] & 077));
496 sidx += 4;
497 didx += 3;
498 }
499 }
500
501 if (didx < len)
502 out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx+1] >> 4) & 003));
503
504 if (++didx < len )
505 out[didx] = (((out[sidx+1] << 4) & 255) | ((out[sidx+2] >> 2) & 017));
506
507 // Resize the output buffer
508 if ( len == 0 || len < out.size() )
509 out.resize(len);
510}
511
512QByteArray KCodecs::uuencode( const QByteArray& in )
513{
514 QByteArray out;
515 uuencode( in, out );
516 return QByteArray( out.data(), out.size()+1 );
517}
518
519void KCodecs::uuencode( const QByteArray& in, QByteArray& out )
520{
521 out.resize( 0 );
522 if( in.isEmpty() )
523 return;
524
525 unsigned int sidx = 0;
526 int didx = 0;
527 unsigned int line_len = 45;
528
529 const char nl[] = "\n";
530 const char* data = in.data();
531 const unsigned int nl_len = strlen(nl);
532 const unsigned int len = in.size();
533
534 out.resize( (len+2)/3*4 + ((len+line_len-1)/line_len)*(nl_len+1) );
535 // split into lines, adding line-length and line terminator
536 while (sidx+line_len < len)
537 {
538 // line length
539 out[didx++] = UUEncMap[line_len];
540
541 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
542 for (unsigned int end = sidx+line_len; sidx < end; sidx += 3)
543 {
544 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
545 out[didx++] = UUEncMap[((data[sidx+1] >> 4) & 017) |
546 ((data[sidx] << 4) & 077)];
547 out[didx++] = UUEncMap[((data[sidx+2] >> 6) & 003) |
548 ((data[sidx+1] << 2) & 077)];
549 out[didx++] = UUEncMap[data[sidx+2] & 077];
550 }
551
552 // line terminator
553 //for (unsigned int idx=0; idx < nl_len; idx++)
554 //out[didx++] = nl[idx];
555 memcpy(out.data()+didx, nl, nl_len);
556 didx += nl_len;
557 }
558
559 // line length
560 out[didx++] = UUEncMap[len-sidx];
561 // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
562 while (sidx+2 < len)
563 {
564 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
565 out[didx++] = UUEncMap[((data[sidx+1] >> 4) & 017) |
566 ((data[sidx] << 4) & 077)];
567 out[didx++] = UUEncMap[((data[sidx+2] >> 6) & 003) |
568 ((data[sidx+1] << 2) & 077)];
569 out[didx++] = UUEncMap[data[sidx+2] & 077];
570 sidx += 3;
571 }
572
573 if (sidx < len-1)
574 {
575 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
576 out[didx++] = UUEncMap[((data[sidx+1] >> 4) & 017) |
577 ((data[sidx] << 4) & 077)];
578 out[didx++] = UUEncMap[(data[sidx+1] << 2) & 077];
579 out[didx++] = UUEncMap[0];
580 }
581 else if (sidx < len)
582 {
583 out[didx++] = UUEncMap[(data[sidx] >> 2) & 077];
584 out[didx++] = UUEncMap[(data[sidx] << 4) & 077];
585 out[didx++] = UUEncMap[0];
586 out[didx++] = UUEncMap[0];
587 }
588
589 // line terminator
590 memcpy(out.data()+didx, nl, nl_len);
591 didx += nl_len;
592
593 // sanity check
594 if ( didx != out.size() )
595 out.resize( 0 );
596}
597
598QByteArray KCodecs::uudecode( const QByteArray& in )
599{
600 QByteArray out;
601 uudecode( in, out );
602 return out;
603}
604
605void KCodecs::uudecode( const QByteArray& in, QByteArray& out )
606{
607 out.resize( 0 );
608 if( in.isEmpty() )
609 return;
610
611 int sidx = 0;
612 int didx = 0;
613 int len = in.size();
614 int line_len, end;
615 const char* data = in.data();
616
617 // Deal with *nix "BEGIN"/"END" separators!!
618 int count = 0;
619 while ( count < len && (data[count] == '\n' || data[count] == '\r' ||
620 data[count] == '\t' || data[count] == ' ') )
621 count ++;
622
623 bool hasLF = false;
624 if ( strncasecmp( data+count, "begin", 5) == 0 )
625 {
626 count += 5;
627 while ( count < len && data[count] != '\n' && data[count] != '\r' )
628 count ++;
629
630 while ( count < len && (data[count] == '\n' || data[count] == '\r') )
631 count ++;
632
633 data += count;
634 len -= count;
635 hasLF = true;
636 }
637
638 out.resize( len/4*3 );
639 while ( sidx < len )
640 {
641 // get line length (in number of encoded octets)
642 line_len = UUDecMap[ (unsigned char) data[sidx++]];
643 // ascii printable to 0-63 and 4-byte to 3-byte conversion
644 end = didx+line_len;
645 char A, B, C, D;
646 if (end > 2) {
647 while (didx < end-2)
648 {
649 A = UUDecMap[(unsigned char) data[sidx]];
650 B = UUDecMap[(unsigned char) data[sidx+1]];
651 C = UUDecMap[(unsigned char) data[sidx+2]];
652 D = UUDecMap[(unsigned char) data[sidx+3]];
653 out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
654 out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
655 out[didx++] = ( ((C << 6) & 255) | (D & 077) );
656 sidx += 4;
657 }
658 }
659
660 if (didx < end)
661 {
662 A = UUDecMap[(unsigned char) data[sidx]];
663 B = UUDecMap[(unsigned char) data[sidx+1]];
664 out[didx++] = ( ((A << 2) & 255) | ((B >> 4) & 003) );
665 }
666
667 if (didx < end)
668 {
669 B = UUDecMap[(unsigned char) data[sidx+1]];
670 C = UUDecMap[(unsigned char) data[sidx+2]];
671 out[didx++] = ( ((B << 4) & 255) | ((C >> 2) & 017) );
672 }
673
674 // skip padding
675 while (sidx < len && data[sidx] != '\n' && data[sidx] != '\r')
676 sidx++;
677
678 // skip end of line
679 while (sidx < len && (data[sidx] == '\n' || data[sidx] == '\r'))
680 sidx++;
681
682 // skip the "END" separator when present.
683 if ( hasLF && strncasecmp( data+sidx, "end", 3) == 0 )
684 break;
685 }
686
687 if ( didx < out.size() )
688 out.resize( didx );
689}
690
691
692
693QString KCodecs::decodeRFC2047String(const QString &msg)
694{
695 QString charset;
696 QChar encoding;
697 QString notEncodedText;
698 QString encodedText;
699 QString decodedText;
700 int encEnd=0;
701 if(!msg.startsWith(QLatin1String("=?")) || (encEnd=msg.lastIndexOf(QLatin1String("?=")))==-1)
702 return msg;
703
704 notEncodedText=msg.mid(encEnd+2);
705 encodedText=msg.left(encEnd);
706 encodedText=encodedText.mid(2,encodedText.length()-2);
707 int questionMark=encodedText.indexOf(QLatin1Char('?'));
708 if (questionMark==-1)
709 return msg;
710 charset=encodedText.left(questionMark).toLower();
711 encoding=encodedText.at(questionMark+1).toLower();
712 if (encoding != QLatin1Char('b') && encoding != QLatin1Char('q'))
713 return msg;
714 encodedText=encodedText.mid(questionMark+3);
715 if(charset.indexOf(QLatin1Char(' '))!=-1 && encodedText.indexOf(QLatin1Char(' '))!=-1)
716 return msg;
717 QByteArray tmpOut;
718 QByteArray tmpIn = encodedText.toLocal8Bit();
719 if(encoding == QLatin1Char('q'))
720 tmpOut = KCodecs::quotedPrintableDecode(tmpIn);
721 else
722 tmpOut = KCodecs::base64Decode(tmpIn);
723 if (charset != QLatin1String("us-ascii")) {
724 QTextCodec *codec = QTextCodec::codecForName(charset.toLocal8Bit());
725 if(!codec)
726 return msg;
727 decodedText = codec->toUnicode(tmpOut);
728 decodedText = decodedText.replace(QLatin1Char('_'), QLatin1Char(' '));
729 } else {
730 decodedText = QString::fromLocal8Bit(tmpOut.replace('_', ' '));
731 }
732
733 return decodedText + notEncodedText;
734}
735
736
737
738
739
740/******************************** KMD5 ********************************/
741KMD5::KMD5()
742{
743 init();
744}
745
746KMD5::KMD5(const char *in, int len)
747{
748 init();
749 update(in, len);
750}
751
752KMD5::KMD5(const QByteArray& in)
753{
754 init();
755 update( in );
756}
757
758KMD5::~KMD5()
759{
760}
761
762void KMD5::update(const QByteArray& in)
763{
764 update(in.data(), int(in.size()));
765}
766
767void KMD5::update(const char* in, int len)
768{
769 update(reinterpret_cast<const unsigned char*>(in), len);
770}
771
772void KMD5::update(const unsigned char* in, int len)
773{
774 if (len < 0)
775 len = qstrlen(reinterpret_cast<const char*>(in));
776
777 if (!len)
778 return;
779
780 if (m_finalized) {
781 kWarning() << "KMD5::update called after state was finalized!";
782 return;
783 }
784
785 quint32 in_index;
786 quint32 buffer_index;
787 quint32 buffer_space;
788 quint32 in_length = static_cast<quint32>( len );
789
790 buffer_index = static_cast<quint32>((m_count[0] >> 3) & 0x3F);
791
792 if ( (m_count[0] += (in_length << 3))<(in_length << 3) )
793 m_count[1]++;
794
795 m_count[1] += (in_length >> 29);
796 buffer_space = 64 - buffer_index;
797
798 if (in_length >= buffer_space)
799 {
800 memcpy (m_buffer + buffer_index, in, buffer_space);
801 transform (m_buffer);
802
803 for (in_index = buffer_space; in_index + 63 < in_length;
804 in_index += 64)
805 transform (reinterpret_cast<const unsigned char*>(in+in_index));
806
807 buffer_index = 0;
808 }
809 else
810 in_index=0;
811
812 memcpy(m_buffer+buffer_index, in+in_index, in_length-in_index);
813}
814
815bool KMD5::update(QIODevice& file)
816{
817 char buffer[1024];
818 int len;
819
820 while ((len=file.read(buffer, sizeof(buffer))) > 0)
821 update(buffer, len);
822
823 return file.atEnd();
824}
825
826void KMD5::finalize ()
827{
828 if (m_finalized) return;
829
830 quint8 bits[8];
831 quint32 index, padLen;
832 static const unsigned char PADDING[64]=
833 {
834 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
835 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
836 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
837 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
838 };
839
840 encode (bits, m_count, 8);
841 //memcpy( bits, m_count, 8 );
842
843 // Pad out to 56 mod 64.
844 index = static_cast<quint32>((m_count[0] >> 3) & 0x3f);
845 padLen = (index < 56) ? (56 - index) : (120 - index);
846 update (reinterpret_cast<const char*>(PADDING), padLen);
847
848 // Append length (before padding)
849 update (reinterpret_cast<const char*>(bits), 8);
850
851 // Store state in digest
852 encode (m_digest, m_state, 16);
853 //memcpy( m_digest, m_state, 16 );
854
855 // Fill sensitive information with zero's
856 memset ( (void *)m_buffer, 0, sizeof(*m_buffer));
857
858 m_finalized = true;
859}
860
861
862bool KMD5::verify( const KMD5::Digest& digest)
863{
864 finalize();
865 return (0 == memcmp(rawDigest(), digest, sizeof(KMD5::Digest)));
866}
867
868bool KMD5::verify( const QByteArray& hexdigest)
869{
870 finalize();
871 return (0 == strcmp(hexDigest().data(), hexdigest));
872}
873
874const KMD5::Digest& KMD5::rawDigest()
875{
876 finalize();
877 return m_digest;
878}
879
880void KMD5::rawDigest( KMD5::Digest& bin )
881{
882 finalize();
883 memcpy( bin, m_digest, 16 );
884}
885
886
887QByteArray KMD5::hexDigest()
888{
889 QByteArray s(32, 0);
890
891 finalize();
892 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
893 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
894 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
895 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
896
897 return s;
898}
899
900void KMD5::hexDigest(QByteArray& s)
901{
902 finalize();
903 s.resize(32);
904 sprintf(s.data(), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
905 m_digest[0], m_digest[1], m_digest[2], m_digest[3], m_digest[4], m_digest[5],
906 m_digest[6], m_digest[7], m_digest[8], m_digest[9], m_digest[10], m_digest[11],
907 m_digest[12], m_digest[13], m_digest[14], m_digest[15]);
908}
909
910QByteArray KMD5::base64Digest()
911{
912 finalize();
913 return QByteArray::fromRawData(reinterpret_cast<const char*>(m_digest),16).toBase64();
914}
915
916void KMD5::init()
917{
918 d = 0;
919 reset();
920}
921
922void KMD5::reset()
923{
924 m_finalized = false;
925
926 m_count[0] = 0;
927 m_count[1] = 0;
928
929 m_state[0] = 0x67452301;
930 m_state[1] = 0xefcdab89;
931 m_state[2] = 0x98badcfe;
932 m_state[3] = 0x10325476;
933
934 memset ( m_buffer, 0, sizeof(*m_buffer));
935 memset ( m_digest, 0, sizeof(*m_digest));
936}
937
938void KMD5::transform( const unsigned char block[64] )
939{
940
941 quint32 a = m_state[0], b = m_state[1], c = m_state[2], d = m_state[3], x[16];
942
943 decode (x, block, 64);
944 //memcpy( x, block, 64 );
945
946 Q_ASSERT(!m_finalized); // not just a user error, since the method is private
947
948 /* Round 1 */
949 FF (a, b, c, d, x[ 0], KMD5_S11, 0xd76aa478); /* 1 */
950 FF (d, a, b, c, x[ 1], KMD5_S12, 0xe8c7b756); /* 2 */
951 FF (c, d, a, b, x[ 2], KMD5_S13, 0x242070db); /* 3 */
952 FF (b, c, d, a, x[ 3], KMD5_S14, 0xc1bdceee); /* 4 */
953 FF (a, b, c, d, x[ 4], KMD5_S11, 0xf57c0faf); /* 5 */
954 FF (d, a, b, c, x[ 5], KMD5_S12, 0x4787c62a); /* 6 */
955 FF (c, d, a, b, x[ 6], KMD5_S13, 0xa8304613); /* 7 */
956 FF (b, c, d, a, x[ 7], KMD5_S14, 0xfd469501); /* 8 */
957 FF (a, b, c, d, x[ 8], KMD5_S11, 0x698098d8); /* 9 */
958 FF (d, a, b, c, x[ 9], KMD5_S12, 0x8b44f7af); /* 10 */
959 FF (c, d, a, b, x[10], KMD5_S13, 0xffff5bb1); /* 11 */
960 FF (b, c, d, a, x[11], KMD5_S14, 0x895cd7be); /* 12 */
961 FF (a, b, c, d, x[12], KMD5_S11, 0x6b901122); /* 13 */
962 FF (d, a, b, c, x[13], KMD5_S12, 0xfd987193); /* 14 */
963 FF (c, d, a, b, x[14], KMD5_S13, 0xa679438e); /* 15 */
964 FF (b, c, d, a, x[15], KMD5_S14, 0x49b40821); /* 16 */
965
966 /* Round 2 */
967 GG (a, b, c, d, x[ 1], KMD5_S21, 0xf61e2562); /* 17 */
968 GG (d, a, b, c, x[ 6], KMD5_S22, 0xc040b340); /* 18 */
969 GG (c, d, a, b, x[11], KMD5_S23, 0x265e5a51); /* 19 */
970 GG (b, c, d, a, x[ 0], KMD5_S24, 0xe9b6c7aa); /* 20 */
971 GG (a, b, c, d, x[ 5], KMD5_S21, 0xd62f105d); /* 21 */
972 GG (d, a, b, c, x[10], KMD5_S22, 0x2441453); /* 22 */
973 GG (c, d, a, b, x[15], KMD5_S23, 0xd8a1e681); /* 23 */
974 GG (b, c, d, a, x[ 4], KMD5_S24, 0xe7d3fbc8); /* 24 */
975 GG (a, b, c, d, x[ 9], KMD5_S21, 0x21e1cde6); /* 25 */
976 GG (d, a, b, c, x[14], KMD5_S22, 0xc33707d6); /* 26 */
977 GG (c, d, a, b, x[ 3], KMD5_S23, 0xf4d50d87); /* 27 */
978 GG (b, c, d, a, x[ 8], KMD5_S24, 0x455a14ed); /* 28 */
979 GG (a, b, c, d, x[13], KMD5_S21, 0xa9e3e905); /* 29 */
980 GG (d, a, b, c, x[ 2], KMD5_S22, 0xfcefa3f8); /* 30 */
981 GG (c, d, a, b, x[ 7], KMD5_S23, 0x676f02d9); /* 31 */
982 GG (b, c, d, a, x[12], KMD5_S24, 0x8d2a4c8a); /* 32 */
983
984 /* Round 3 */
985 HH (a, b, c, d, x[ 5], KMD5_S31, 0xfffa3942); /* 33 */
986 HH (d, a, b, c, x[ 8], KMD5_S32, 0x8771f681); /* 34 */
987 HH (c, d, a, b, x[11], KMD5_S33, 0x6d9d6122); /* 35 */
988 HH (b, c, d, a, x[14], KMD5_S34, 0xfde5380c); /* 36 */
989 HH (a, b, c, d, x[ 1], KMD5_S31, 0xa4beea44); /* 37 */
990 HH (d, a, b, c, x[ 4], KMD5_S32, 0x4bdecfa9); /* 38 */
991 HH (c, d, a, b, x[ 7], KMD5_S33, 0xf6bb4b60); /* 39 */
992 HH (b, c, d, a, x[10], KMD5_S34, 0xbebfbc70); /* 40 */
993 HH (a, b, c, d, x[13], KMD5_S31, 0x289b7ec6); /* 41 */
994 HH (d, a, b, c, x[ 0], KMD5_S32, 0xeaa127fa); /* 42 */
995 HH (c, d, a, b, x[ 3], KMD5_S33, 0xd4ef3085); /* 43 */
996 HH (b, c, d, a, x[ 6], KMD5_S34, 0x4881d05); /* 44 */
997 HH (a, b, c, d, x[ 9], KMD5_S31, 0xd9d4d039); /* 45 */
998 HH (d, a, b, c, x[12], KMD5_S32, 0xe6db99e5); /* 46 */
999 HH (c, d, a, b, x[15], KMD5_S33, 0x1fa27cf8); /* 47 */
1000 HH (b, c, d, a, x[ 2], KMD5_S34, 0xc4ac5665); /* 48 */
1001
1002 /* Round 4 */
1003 II (a, b, c, d, x[ 0], KMD5_S41, 0xf4292244); /* 49 */
1004 II (d, a, b, c, x[ 7], KMD5_S42, 0x432aff97); /* 50 */
1005 II (c, d, a, b, x[14], KMD5_S43, 0xab9423a7); /* 51 */
1006 II (b, c, d, a, x[ 5], KMD5_S44, 0xfc93a039); /* 52 */
1007 II (a, b, c, d, x[12], KMD5_S41, 0x655b59c3); /* 53 */
1008 II (d, a, b, c, x[ 3], KMD5_S42, 0x8f0ccc92); /* 54 */
1009 II (c, d, a, b, x[10], KMD5_S43, 0xffeff47d); /* 55 */
1010 II (b, c, d, a, x[ 1], KMD5_S44, 0x85845dd1); /* 56 */
1011 II (a, b, c, d, x[ 8], KMD5_S41, 0x6fa87e4f); /* 57 */
1012 II (d, a, b, c, x[15], KMD5_S42, 0xfe2ce6e0); /* 58 */
1013 II (c, d, a, b, x[ 6], KMD5_S43, 0xa3014314); /* 59 */
1014 II (b, c, d, a, x[13], KMD5_S44, 0x4e0811a1); /* 60 */
1015 II (a, b, c, d, x[ 4], KMD5_S41, 0xf7537e82); /* 61 */
1016 II (d, a, b, c, x[11], KMD5_S42, 0xbd3af235); /* 62 */
1017 II (c, d, a, b, x[ 2], KMD5_S43, 0x2ad7d2bb); /* 63 */
1018 II (b, c, d, a, x[ 9], KMD5_S44, 0xeb86d391); /* 64 */
1019
1020 m_state[0] += a;
1021 m_state[1] += b;
1022 m_state[2] += c;
1023 m_state[3] += d;
1024
1025 memset ( static_cast<void *>(x), 0, sizeof(x) );
1026}
1027
1028inline quint32 KMD5::rotate_left (quint32 x, quint32 n)
1029{
1030 return (x << n) | (x >> (32-n)) ;
1031}
1032
1033inline quint32 KMD5::F (quint32 x, quint32 y, quint32 z)
1034{
1035 return (x & y) | (~x & z);
1036}
1037
1038inline quint32 KMD5::G (quint32 x, quint32 y, quint32 z)
1039{
1040 return (x & z) | (y & ~z);
1041}
1042
1043inline quint32 KMD5::H (quint32 x, quint32 y, quint32 z)
1044{
1045 return x ^ y ^ z;
1046}
1047
1048inline quint32 KMD5::I (quint32 x, quint32 y, quint32 z)
1049{
1050 return y ^ (x | ~z);
1051}
1052
1053void KMD5::FF ( quint32& a, quint32 b, quint32 c, quint32 d,
1054 quint32 x, quint32 s, quint32 ac )
1055{
1056 a += F(b, c, d) + x + ac;
1057 a = rotate_left (a, s) +b;
1058}
1059
1060void KMD5::GG ( quint32& a, quint32 b, quint32 c, quint32 d,
1061 quint32 x, quint32 s, quint32 ac)
1062{
1063 a += G(b, c, d) + x + ac;
1064 a = rotate_left (a, s) +b;
1065}
1066
1067void KMD5::HH ( quint32& a, quint32 b, quint32 c, quint32 d,
1068 quint32 x, quint32 s, quint32 ac )
1069{
1070 a += H(b, c, d) + x + ac;
1071 a = rotate_left (a, s) +b;
1072}
1073
1074void KMD5::II ( quint32& a, quint32 b, quint32 c, quint32 d,
1075 quint32 x, quint32 s, quint32 ac )
1076{
1077 a += I(b, c, d) + x + ac;
1078 a = rotate_left (a, s) +b;
1079}
1080
1081
1082void KMD5::encode ( unsigned char* output, quint32 *in, quint32 len )
1083{
1084#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
1085 memcpy(output, in, len);
1086#else
1087 quint32 i, j;
1088 for (i = 0, j = 0; j < len; i++, j += 4)
1089 {
1090 output[j] = static_cast<quint8>((in[i] & 0xff));
1091 output[j+1] = static_cast<quint8>(((in[i] >> 8) & 0xff));
1092 output[j+2] = static_cast<quint8>(((in[i] >> 16) & 0xff));
1093 output[j+3] = static_cast<quint8>(((in[i] >> 24) & 0xff));
1094 }
1095#endif
1096}
1097
1098// Decodes in (quint8) into output (quint32). Assumes len is a
1099// multiple of 4.
1100void KMD5::decode (quint32 *output, const unsigned char* in, quint32 len)
1101{
1102#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
1103 memcpy(output, in, len);
1104
1105#else
1106 quint32 i, j;
1107 for (i = 0, j = 0; j < len; i++, j += 4)
1108 output[i] = static_cast<quint32>(in[j]) |
1109 (static_cast<quint32>(in[j+1]) << 8) |
1110 (static_cast<quint32>(in[j+2]) << 16) |
1111 (static_cast<quint32>(in[j+3]) << 24);
1112#endif
1113}
1114
1115
1116
1117/**************************************************************/
KMD5::update
void update(const char *in, int len=-1)
Updates the message to be digested.
Definition: kcodecs.cpp:767
KMD5::rawDigest
const Digest & rawDigest()
Definition: kcodecs.cpp:874
KMD5::transform
void transform(const unsigned char buffer[64])
Performs the real update work.
Definition: kcodecs.cpp:938
KMD5::hexDigest
QByteArray hexDigest()
Returns the value of the calculated message digest in a hexadecimal representation.
Definition: kcodecs.cpp:887
KMD5::base64Digest
QByteArray base64Digest()
Returns the value of the calculated message digest in a base64-encoded representation.
Definition: kcodecs.cpp:910
KMD5::reset
void reset()
Calling this function will reset the calculated message digest.
Definition: kcodecs.cpp:922
KMD5::~KMD5
~KMD5()
Definition: kcodecs.cpp:758
KMD5::Digest
unsigned char Digest[16]
Definition: kcodecs.h:335
KMD5::finalize
void finalize()
finalizes the digest
Definition: kcodecs.cpp:826
KMD5::KMD5
KMD5()
Definition: kcodecs.cpp:741
KMD5::verify
bool verify(const KMD5::Digest &digest)
returns true if the calculated digest for the given message matches the given one.
Definition: kcodecs.cpp:862
QIODevice
QString
quint32
output
void output(QList< Action > actions, QHash< QString, QString > domain)
Definition: fake/kauth-policy-gen-polkit.cpp:41
kWarning
#define kWarning
Definition: kdebug.h:322
KMD5_S33
#define KMD5_S33
Definition: kcodecs.cpp:54
KMD5_S32
#define KMD5_S32
Definition: kcodecs.cpp:53
KMD5_S14
#define KMD5_S14
Definition: kcodecs.cpp:47
KMD5_S41
#define KMD5_S41
Definition: kcodecs.cpp:56
KMD5_S22
#define KMD5_S22
Definition: kcodecs.cpp:49
KMD5_S12
#define KMD5_S12
Definition: kcodecs.cpp:45
KMD5_S42
#define KMD5_S42
Definition: kcodecs.cpp:57
KMD5_S13
#define KMD5_S13
Definition: kcodecs.cpp:46
rikFindChar
static int rikFindChar(register const char *_s, const char c)
Definition: kcodecs.cpp:141
KMD5_S23
#define KMD5_S23
Definition: kcodecs.cpp:50
KMD5_S44
#define KMD5_S44
Definition: kcodecs.cpp:59
KMD5_S43
#define KMD5_S43
Definition: kcodecs.cpp:58
KMD5_S34
#define KMD5_S34
Definition: kcodecs.cpp:55
KMD5_S21
#define KMD5_S21
Definition: kcodecs.cpp:48
KMD5_S31
#define KMD5_S31
Definition: kcodecs.cpp:52
KMD5_S11
#define KMD5_S11
Definition: kcodecs.cpp:44
KMD5_S24
#define KMD5_S24
Definition: kcodecs.cpp:51
kcodecs.h
kdebug.h
F
#define F
I
#define I
KCodecs
A wrapper class for the most commonly used encoding and decoding algorithms.
Definition: kcodecs.cpp:62
KCodecs::UUEncMap
static const char UUEncMap[64]
Definition: kcodecs.cpp:96
KCodecs::UUDecMap
static const char UUDecMap[128]
Definition: kcodecs.cpp:108
KCodecs::base64Decode
QByteArray base64Decode(const QByteArray &in)
Decodes the given data that was encoded using the base64 algorithm.
Definition: kcodecs.cpp:424
KCodecs::decodeRFC2047String
QString decodeRFC2047String(const QString &text)
Decodes string text according to RFC2047, i.e., the construct =?charset?[qb]?encoded?...
Definition: kcodecs.cpp:693
KCodecs::maxQPLineLength
static const unsigned int maxQPLineLength
Definition: kcodecs.cpp:134
KCodecs::uuencode
QByteArray uuencode(const QByteArray &in)
Encodes the given data using the uuencode algorithm.
Definition: kcodecs.cpp:512
KCodecs::Base64DecMap
static const char Base64DecMap[128]
Definition: kcodecs.cpp:76
KCodecs::Base64EncMap
static const char Base64EncMap[64]
Definition: kcodecs.cpp:64
KCodecs::base64Encode
QByteArray base64Encode(const QByteArray &in, bool insertLFs=false)
Encodes the given data using the base64 algorithm.
Definition: kcodecs.cpp:345
KCodecs::quotedPrintableDecode
QByteArray quotedPrintableDecode(const QByteArray &in)
Decodes a quoted-printable encoded data.
Definition: kcodecs.cpp:279
KCodecs::quotedPrintableEncode
QByteArray quotedPrintableEncode(const QByteArray &in, bool useCRLF=true)
Encodes the given data using the quoted-printable algorithm.
Definition: kcodecs.cpp:156
KCodecs::uudecode
QByteArray uudecode(const QByteArray &in)
Decodes the given data using the uudecode algorithm.
Definition: kcodecs.cpp:598
KCodecs::hexChars
static const char hexChars[16]
Definition: kcodecs.cpp:128
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal