piler/src/decoder.c

371 lines
8.2 KiB
C
Raw Normal View History

2011-11-14 15:57:52 +01:00
/*
* decoder.c, SJ
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "decoder.h"
#include "htmlentities.h"
#include "config.h"
static int b64[] = {
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 0, 255, 255,
255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 255, 255, 255, 255, 255,
255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255
};
static char hex_table[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static int compmi(const void *m1, const void *m2){
struct mi *mi1 = (struct mi *) m1;
struct mi *mi2 = (struct mi *) m2;
return strcmp(mi1->entity, mi2->entity);
}
void sanitiseBase64(char *s){
char *p1;
if(s == NULL) return;
for(; *s; s++){
if(b64[(unsigned int)(*s & 0xFF)] == 255){
for(p1 = s; p1[0] != '\0'; p1++)
p1[0] = p1[1];
}
}
}
2012-09-07 15:08:50 +02:00
inline void pack_4_into_3(char *s, char *s2){
int j, n[4], k1, k2;
memset(s2, 0, 3);
if(strlen(s) != 4) return;
for(j=0; j<4; j++){
k1 = s[j];
n[j] = b64[k1];
}
k1 = n[0]; k1 = k1 << 2;
k2 = n[1]; k2 = k2 >> 4;
s2[0] = k1 | k2;
k1 = (n[1] & 0x0F) << 4;
k2 = n[2]; k2 = k2 >> 2;
s2[1] = k1 | k2;
k1 = n[2] << 6;
k2 = n[3] >> 0;
s2[2] = k1 | k2;
}
2011-11-14 15:57:52 +01:00
int decodeBase64(char *p){
2012-09-07 15:08:50 +02:00
int i, len=0;
2011-11-14 15:57:52 +01:00
char s[5], s2[3], puf[MAXBUFSIZE];
if(strlen(p) < 4 || strlen(p) > MAXBUFSIZE/2)
return 0;
for(i=0; i<strlen(p); i++){
memcpy(s, p+i, 4);
s[4] = '\0';
i += 3;
/* safety check against abnormally long lines */
if(len + 3 > sizeof(puf)-1) break;
2011-11-14 15:57:52 +01:00
if(strlen(s) == 4){
2012-09-07 15:08:50 +02:00
pack_4_into_3(s, s2);
memcpy(puf+len, s2, 3);
len += 3;
}
}
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
*(puf+len) = '\0';
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
snprintf(p, MAXBUFSIZE-1, "%s", puf);
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
return len;
}
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
int decode_base64_to_buffer(char *p, int plen, unsigned char *b, int blen){
int i, len=0;
char s[5], s2[3];
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
if(plen < 4 || plen > blen)
return 0;
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
for(i=0; i<plen; i++){
memcpy(s, p+i, 4);
s[4] = '\0';
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
i += 3;
2011-11-14 15:57:52 +01:00
2012-09-07 15:08:50 +02:00
/* safety check against abnormally long lines */
if(len + 3 > blen-1) break;
if(strlen(s) == 4){
pack_4_into_3(s, s2);
memcpy(b+len, s2, 3);
2011-11-14 15:57:52 +01:00
len += 3;
}
}
return len;
}
void decodeQP(char *p){
int i, k=0, a, b;
char c;
if(p == NULL) return;
for(i=0; i<strlen((char*)p); i++){
c = p[i];
if(p[i] == '=' && isxdigit(p[i+1]) && isxdigit(p[i+2])){
a = p[i+1];
b = p[i+2];
c = 16 * hex_table[a] + hex_table[b];
i += 2;
}
p[k] = c;
k++;
}
p[k] = '\0';
}
2011-12-07 15:24:52 +01:00
void decodeHTML(char *p){
unsigned char buf[MAXBUFSIZE], __u[8];
char *s, *q;
int count=0, len, c;
2011-11-14 15:57:52 +01:00
struct mi key, *res;
2011-12-07 15:24:52 +01:00
if(p == NULL || strlen(p) == 0) return;
2011-11-14 15:57:52 +01:00
2011-12-07 15:24:52 +01:00
s = p;
2011-11-14 15:57:52 +01:00
2011-12-07 15:24:52 +01:00
memset(buf, 0, sizeof(buf));
2011-11-14 15:57:52 +01:00
2011-12-07 15:24:52 +01:00
for(; *s; s++){
if(*s == '&'){
q = strchr(s, ';');
if(q){
*q = '\0';
if(*(s+1) == '#'){
c = atoi(s+2);
if(c == 0) c = 'q';
buf[count] = (unsigned char)c;
count++;
2011-11-14 15:57:52 +01:00
}
else {
2011-12-07 15:24:52 +01:00
key.entity = s;
2011-11-14 15:57:52 +01:00
res = bsearch(&key, htmlentities, NUM_OF_HTML_ENTITIES, sizeof(struct mi), compmi);
2011-12-07 15:24:52 +01:00
if(res && res->val <= 255){
utf8_encode_char(res->val, &__u[0], sizeof(__u), &len);
memcpy(&buf[count], &__u[0], len);
count += len;
}
else {
buf[count] = 'q';
count++;
}
2011-11-14 15:57:52 +01:00
}
2011-12-07 15:24:52 +01:00
s = q;
2011-11-14 15:57:52 +01:00
}
2011-12-07 15:24:52 +01:00
}
else {
buf[count] = *s;
count++;
}
2011-11-14 15:57:52 +01:00
}
2011-12-07 15:24:52 +01:00
buf[count] = '\0'; count++;
memcpy(p, buf, count);
2011-11-14 15:57:52 +01:00
}
void decodeURL(char *p){
int i, c, k=0, a, b;
if(p == NULL) return;
for(i=0; i<strlen(p); i++){
switch(p[i]){
case '+':
c = ' ';
break;
case '%':
if(isxdigit(p[i+1]) && isxdigit(p[i+2])){
a = p[i+1];
b = p[i+2];
c = 16 * hex_table[a] + hex_table[b];
i += 2;
}
else
c = p[i];
break;
default:
c = p[i];
break;
}
p[k] = c;
k++;
}
p[k] = '\0';
}
2011-12-07 15:24:52 +01:00
inline void utf8_encode_char(unsigned char c, unsigned char *buf, int buflen, int *len){
int count=0;
memset(buf, 0, buflen);
/*
* Code point 1st byte 2nd byte 3rd byte 4th byte
* ---------- -------- -------- -------- --------
* U+0000..U+007F 00..7F
* U+0080..U+07FF C2..DF 80..BF
* U+0800..U+0FFF E0 A0..BF 80..BF
*/
if(c <= 0x7F){
*(buf+count) = c;
count++;
}
else if(c <= 0x7FF){
*(buf+count) = ( 0xC0 | (c >> 6) );
count++;
*(buf+count) = ( 0x80 | (c & 0x3F) );
count++;
}
else if (c <= 0xFFFF){
*(buf+count) = ( 0xE0 | (c >> 12) );
count++;
*(buf+count) = ( 0x80 | ((c >> 6) & 0x3F) );
count++;
*(buf+count) = ( 0x80 | (c & 0x3F) );
count++;
}
*len = count;
}
void utf8_encode(unsigned char *p){
int count=0, len;
unsigned char *u, *s, utf8[MAXBUFSIZE], __u[8];
if(p == NULL || strlen((char *)p) == 0) return;
memset(utf8, 0, MAXBUFSIZE);
u = &utf8[0];
s = p;
for(; *s; s++){
utf8_encode_char(*s, &__u[0], sizeof(__u), &len);
/*
* this condition should never happen, as according to the RFCs:
*
* "Each line of characters MUST be no more than 998 characters, and
* SHOULD be no more than 78 characters, excluding the CRLF."
*
*/
if(count+len > sizeof(utf8)-1) break;
2011-12-07 15:24:52 +01:00
//printf("%s", __u);
memcpy(u+count, &__u[0], len);
count += len;
}
*(u+count) = '\0'; count++;
memcpy(p, u, count);
}