void usb_keyboard_class::write(uint8_t c) #endif { if (c < 0x80) { // single byte encoded, 0x00 to 0x7F utf8_state = 0; write_unicode(c); } else if (c < 0xC0) { // 2nd, 3rd or 4th byte, 0x80 to 0xBF c &= 0x3F; if (utf8_state == 1) { utf8_state = 0; write_unicode(unicode_wchar | c); } else if (utf8_state == 2) { unicode_wchar |= ((uint16_t)c << 6); utf8_state = 1; } } else if (c < 0xE0) { // begin 2 byte sequence, 0xC2 to 0xDF // or illegal 2 byte sequence, 0xC0 to 0xC1 unicode_wchar = (uint16_t)(c & 0x1F) << 6; utf8_state = 1; } else if (c < 0xF0) { // begin 3 byte sequence, 0xE0 to 0xEF unicode_wchar = (uint16_t)(c & 0x0F) << 12; utf8_state = 2; } else { // begin 4 byte sequence (not supported), 0xF0 to 0xF4 // or illegal, 0xF5 to 0xFF utf8_state = 255; } #if ARDUINO >= 100 return 1; #endif }
static int write_uri(unsigned char **buffer_ptr, int *buffer_len_ptr, string *str) { char uri[SIZE_URI]; unsigned char *buffer = *buffer_ptr; int buffer_len = *buffer_len_ptr; int i; for (i = 0; buffer_len && *buffer && (strchr(legalchars, *buffer) || *buffer > 127) && i < SIZE_URI-1; i++) { uri[i] = *buffer++; buffer_len--; } /* The is probably the end of a sentence */ if (i > 0 && strchr(".?!", uri[i-1])) --i; uri[i] = 0; if (i) { string_append(str,"<A HREF=\""); string_append(str,uri); string_append(str,"\""); if (!user.config.read_link_underlined) string_append(str," STYLE=\"TEXT-DECORATION: none\""); string_append(str,">"); write_unicode(uri,str); string_append(str,"</A>"); } *buffer_ptr = buffer; *buffer_len_ptr = buffer_len; return 1; }
SaneWinMain( argc, argv ) { FILE *input; if( argc > 2 ) { input = sack_fopen( 0, argv[2], WIDE("rb+") ); if( input ) { if( StrCaseCmpEx( argv[1], WIDE( "u" ), 1 ) == 0 ) { read_ascii( input ); ascii_to_unicode(); write_unicode( input ); } else { read_unicode( input ); unicode_to_ascii(); write_ascii( input ); } fclose( input ); } else printf( WIDE( "Failed to open %s" ), argv[2] ); } else { printf( WIDE("Usage: %s [u/a] [filename]\n"), argv[0] ); printf( WIDE(" u or a is unicode or ascii mode; unicode translates from ascii to unicode\n") ); printf( WIDE(" ascii translates from unicode to ascii\n") ); printf( WIDE(" file will be written back in-place\n") ); } return 0; }
/* * Returns 1 on memory error condition */ int str_convert( str *s, int charsetin, int latexin, int utf8in, int xmlin, int charsetout, int latexout, int utf8out, int xmlout ) { unsigned int pos = 0; unsigned int ch; str ns; int ok = 1; if ( !s || s->len==0 ) return ok; /* Ensure that string is internally allocated. * This fixes NULL pointer derefernce in CVE-2018-10775 in bibutils * as a string with a valid data pointer is potentially replaced * by a string without a valid data pointer due to it being invalid * unicode. * This probably also fixes CVE-2018-10773 and CVE-2018-10774 which * are NULL dereferences also likely due to a fuzzer, but without * test cases in the report, I can't be completely sure. */ str_initstrc( &ns, "" ); if ( charsetin==CHARSET_UNKNOWN ) charsetin = CHARSET_DEFAULT; if ( charsetout==CHARSET_UNKNOWN ) charsetout = CHARSET_DEFAULT; while ( s->data[pos] ) { ch = get_unicode( s, &pos, charsetin, latexin, utf8in, xmlin ); ok = write_unicode( &ns, ch, charsetout, latexout, utf8out, xmlout ); if ( !ok ) goto out; } str_swapstrings( s, &ns ); out: str_free( &ns ); return ok; }
char *text2html(unsigned char *buffer, int buffer_len, int flags, const char *fonttag) { unsigned char *saved_buffer = buffer; string str; if (string_initialize(&str,1024)) { char buf[512]; int last_color = 0; /* the color of the current line */ int eval_color = 2; /* recheck the color */ int initial_color = 1; int level = 0; int line = 0; /* the type of the line */ if (flags & TEXT2HTML_BODY_TAG) { sm_snprintf(buf,sizeof(buf),"<BODY BGCOLOR=\"#%06x\" TEXT=\"#%06x\" LINK=\"#%06x\">",user.config.read_background,user.config.read_text,user.config.read_link); string_append(&str,buf); } string_append(&str,fonttag); /* accepts NULL pointer */ /* check for >0, otherwise we'll be in an endless loop if buffer_len becomes <0 */ while (buffer_len > 0) { if (eval_color) { int new_level = 0; int buffer2_len = buffer_len; unsigned char *buffer2 = buffer; int new_color = 0; /* Determine the citation level. Afterwards, buffer2 will point to the end of the citation symbols. */ while (buffer2_len) { unsigned char c = *buffer2; if (c == '>') { new_level++; if (new_color == 1) new_color = 2; else new_color = 1; } else { if (c != ' ') break; if (c == ' ' && !new_level) break; } buffer2_len--; buffer2++; } if (user.config.read_graphical_quote_bar) { /* When graphical quote bar is enabled we skip all quotation symbols */ buffer = buffer2; buffer_len = buffer2_len; if (level != new_level) { const char *begin_quote_string = "<TABLE BGCOLOR=\"#%06x\" WIDTH=\"100%%\" STYLE=\"border-left: 3px solid #%06x; border-right: 3px solid #%06x;\"><TD><FONT COLOR=\"#%06x\">"; const char *end_quote_string = "</FONT></TD></TABLE>"; /* If new level is larger */ for (;level < new_level; level++) { unsigned int color = level%2?user.config.read_quoted:user.config.read_old_quoted; sm_snprintf(buf,sizeof(buf),begin_quote_string,user.config.read_quoted_background,color,color,color); string_append(&str,buf); } /* If new level is lower */ for (;level > new_level; level--) string_append(&str,end_quote_string); } } else { if (last_color != new_color) { const char *begin_quote_string = "<FONT COLOR=\"#%x\">"; const char *end_quote_string = "</FONT>"; if (!initial_color) string_append(&str,end_quote_string); if (new_color == 1) { sm_snprintf(buf,sizeof(buf),begin_quote_string,user.config.read_quoted); string_append(&str,buf); } else if (new_color == 2) { sm_snprintf(buf,sizeof(buf),begin_quote_string,user.config.read_old_quoted); string_append(&str,buf); } last_color = new_color; if (new_color) initial_color = 0; else initial_color = 1; } } eval_color = 0; } if (!mystrnicmp("http:",(char*)buffer,5)) write_uri(&buffer, &buffer_len, &str); else if (!mystrnicmp("mailto:",(char*)buffer,7)) write_uri(&buffer, &buffer_len, &str); else if (!mystrnicmp("ftp:",(char*)buffer,4)) write_uri(&buffer, &buffer_len, &str); else if (!mystrnicmp("https:",(char*)buffer,6)) write_uri(&buffer, &buffer_len, &str); else { unsigned char c; c = *buffer; if ((c == '@') && (buffer > saved_buffer)) { /* A @ has been encountered, check if this belongs to an email adresse by traversing back * within the string */ unsigned char *buffer2 = buffer - 1; unsigned char *buffer3; unsigned char c2; int buffer2_len = buffer_len + 1; char *address; while ((c2 = *buffer2) && buffer2 > saved_buffer) { static const char noaliaschars[] = { " ()<>@,;:\\\"[]\n\r"}; if (strchr(noaliaschars,c2)) { buffer2++; break; } buffer2_len++; buffer2--; } if ((buffer3 = (unsigned char*)parse_addr_spec((char*)buffer2, &address))) { int email_len; /* crop the string to the beginning of the email address */ string_crop(&str,0,str.len - (buffer - buffer2)); buffer_len += buffer - buffer2; buffer -= buffer - buffer2; email_len = buffer3 - buffer; buffer_len -= email_len; buffer = buffer3; sm_snprintf(buf,sizeof(buf),"<A HREF=\"mailto:%s\"%s>",address, user.config.read_link_underlined?"":" STYLE=\"TEXT-DECORATION: none\""); string_append(&str,buf); write_unicode(address,&str); string_append(&str,"</A>"); free(address); continue; } } if (user.config.read_smilies) { unsigned int i; int smily_used = 0; /* No look into the smily table, this is slow and needs to be improved */ for (i=0;i<sizeof(smily)/sizeof(struct smily);i++) { if (!strncmp(smily[i].ascii,(char*)buffer,strlen(smily[i].ascii))) { buffer += strlen(smily[i].ascii); buffer_len -= strlen(smily[i].ascii); sm_snprintf(buf,sizeof(buf),"<IMG SRC=\"PROGDIR:Images/%s\" VALIGN=\"middle\" ALT=\"%s\">",smily[i].gfx,smily[i].ascii); string_append(&str,buf); smily_used = 1; } } if (smily_used) continue; } if (!strncmp("\n<sb>",(char*)buffer,5)) { if (line) string_append(&str,"<BR></TD><TD WIDTH=\"50%\"><HR></TD></TR></TABLE>"); line = 1; buffer += 5; buffer_len -= 5; string_append(&str,"<TABLE WIDTH=\"100%\" BORDER=\"0\"><TR><TD VALIGN=\"middle\" WIDTH=\"50%\"><HR></TD><TD>"); continue; } if (!strncmp("\n<tsb>",(char*)buffer,6)) { if (line) string_append(&str,"<BR></TD><TD WIDTH=\"50%\"><HR></TD></TR></TABLE>"); line = 2; buffer += 6; buffer_len -= 6; string_append(&str,"<TABLE WIDTH=\"100%\" BORDER=\"0\"><TR><TD VALIGN=\"middle\" WIDTH=\"50%\"><HR></TD><TD>"); continue; } if (c < 128) { buffer++; buffer_len--; if (c== '<') string_append(&str,"<"); else if (c== '>') string_append(&str,">"); else if (c== '&') string_append(&str,"&"); else if (c == 10) { eval_color = 1; string_append(&str,"<BR>\n"); if (line) { string_append(&str,"</TD><TD WIDTH=\"50%\"><HR></TD></TR></TABLE>"); line = 0; } } else { if (c == 32) { if (*buffer == 32 || (flags & TEXT2HTML_NOWRAP)) string_append(&str," "); else string_append(&str," "); } else { if (c) { string_append_part(&str,(char*)&c,1); } } } } else { unsigned int unicode; int len = 0; /* check if it really could be a utf8 char */ if (utf8islegal((utf8*)buffer, (utf8*)(buffer+buffer_len))) { len = utf8tochar((utf8*)buffer, &unicode, user.config.default_codeset); } if ((len == 0) || (len > buffer_len)) { /* something wrong with that utf8 sequence */ unicode = '?'; len = 1; } buffer_len -= len; buffer += len; if (unicode == 0) unicode = '_'; sm_snprintf(buf,sizeof(buf),"&#%d;",unicode); string_append(&str,buf); } } } if (fonttag) string_append(&str,"</FONT>"); if (flags & TEXT2HTML_ENDBODY_TAG) string_append(&str,"</BODY>"); SM_DEBUGF(20,("%s\n",str.str)); return str.str; } return NULL; }
void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) { GPtrArray *objects = NULL; GHashTable *ref_table = NULL; struct serialize_s ser_s; uint8_t offset_size = 0; uint8_t dict_param_size = 0; uint64_t num_objects = 0; uint64_t root_object = 0; uint64_t offset_table_index = 0; GByteArray *bplist_buff = NULL; uint64_t i = 0; uint8_t *buff = NULL; uint64_t *offsets = NULL; uint8_t pad[6] = { 0, 0, 0, 0, 0, 0 }; uint8_t trailer[BPLIST_TRL_SIZE]; //for string glong len = 0; int type = 0; glong items_read = 0; glong items_written = 0; GError *error = NULL; gunichar2 *unicodestr = NULL; //check for valid input if (!plist || !plist_bin || *plist_bin || !length) return; //list of objects objects = g_ptr_array_new(); //hashtable to write only once same nodes ref_table = g_hash_table_new(plist_data_hash, plist_data_compare); //serialize plist ser_s.objects = objects; ser_s.ref_table = ref_table; serialize_plist(plist, &ser_s); //now stream to output buffer offset_size = 0; //unknown yet dict_param_size = get_needed_bytes(objects->len); num_objects = objects->len; root_object = 0; //root is first in list offset_table_index = 0; //unknown yet //setup a dynamic bytes array to store bplist in bplist_buff = g_byte_array_new(); //set magic number and version g_byte_array_append(bplist_buff, BPLIST_MAGIC, BPLIST_MAGIC_SIZE); g_byte_array_append(bplist_buff, BPLIST_VERSION, BPLIST_VERSION_SIZE); //write objects and table offsets = (uint64_t *) malloc(num_objects * sizeof(uint64_t)); for (i = 0; i < num_objects; i++) { plist_data_t data = plist_get_data(g_ptr_array_index(objects, i)); offsets[i] = bplist_buff->len; switch (data->type) { case PLIST_BOOLEAN: buff = (uint8_t *) malloc(sizeof(uint8_t)); buff[0] = data->boolval ? BPLIST_TRUE : BPLIST_FALSE; g_byte_array_append(bplist_buff, buff, sizeof(uint8_t)); free(buff); break; case PLIST_UINT: write_int(bplist_buff, data->intval); break; case PLIST_REAL: write_real(bplist_buff, data->realval); break; case PLIST_KEY: case PLIST_STRING: len = strlen(data->strval); if ( is_ascii_string(data->strval, len) ) { write_string(bplist_buff, data->strval); } else { unicodestr = g_utf8_to_utf16(data->strval, len, &items_read, &items_written, &error); write_unicode(bplist_buff, unicodestr, items_written); g_free(unicodestr); } break; case PLIST_DATA: write_data(bplist_buff, data->buff, data->length); case PLIST_ARRAY: write_array(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); break; case PLIST_DICT: write_dict(bplist_buff, g_ptr_array_index(objects, i), ref_table, dict_param_size); break; case PLIST_DATE: write_date(bplist_buff, data->timeval.tv_sec + (double) data->timeval.tv_usec / G_USEC_PER_SEC); break; default: break; } } //free intermediate objects g_hash_table_foreach_remove(ref_table, free_index, NULL); g_ptr_array_free(objects, TRUE); g_hash_table_destroy(ref_table); //write offsets offset_size = get_needed_bytes(bplist_buff->len); offset_table_index = bplist_buff->len; for (i = 0; i < num_objects; i++) { uint8_t *offsetbuff = (uint8_t *) malloc(offset_size); #if G_BYTE_ORDER == G_BIG_ENDIAN offsets[i] = offsets[i] << ((sizeof(uint64_t) - offset_size) * 8); #endif memcpy(offsetbuff, &offsets[i], offset_size); byte_convert(offsetbuff, offset_size); g_byte_array_append(bplist_buff, offsetbuff, offset_size); free(offsetbuff); } //experimental pad to reflect apple's files g_byte_array_append(bplist_buff, pad, 6); //setup trailer num_objects = GUINT64_FROM_BE(num_objects); root_object = GUINT64_FROM_BE(root_object); offset_table_index = GUINT64_FROM_BE(offset_table_index); memcpy(trailer + BPLIST_TRL_OFFSIZE_IDX, &offset_size, sizeof(uint8_t)); memcpy(trailer + BPLIST_TRL_PARMSIZE_IDX, &dict_param_size, sizeof(uint8_t)); memcpy(trailer + BPLIST_TRL_NUMOBJ_IDX, &num_objects, sizeof(uint64_t)); memcpy(trailer + BPLIST_TRL_ROOTOBJ_IDX, &root_object, sizeof(uint64_t)); memcpy(trailer + BPLIST_TRL_OFFTAB_IDX, &offset_table_index, sizeof(uint64_t)); g_byte_array_append(bplist_buff, trailer, BPLIST_TRL_SIZE); //duplicate buffer *plist_bin = (char *) malloc(bplist_buff->len); memcpy(*plist_bin, bplist_buff->data, bplist_buff->len); *length = bplist_buff->len; g_byte_array_free(bplist_buff, TRUE); free(offsets); }