const char * auto_recode(const char *utf_str) { char *res; static char result_buf[MAX_BUFSIZE]; if (is_ascii_string (utf_str)) { res = (char*)utf_str; } else if (utf8_validate (utf_str)) { /* UTF-8 string */ /* Replace em dash with "#$%" sequence */ const char *utf_src = utf_str; char iso_8859_1[MAX_BUFSIZE]; if (simple_recode (utf_str, "UTF-8", "ISO8859-1", iso_8859_1) && utf8_validate(iso_8859_1)) utf_src = iso_8859_1; /* Now find out, how is UTF-8 string constructed */ if (is_cp1251 (utf_src)) { /* May be ISO8859-1 or CP1251 */ char tmp[MAX_BUFSIZE]; res = simple_recode (utf_src, "UTF-8", "ISO8859-1", tmp); if (res) res = simple_recode (res, "CP1251", "UTF-8", result_buf); if (!res) res = (char*)utf_src; } else { res = strncpy(result_buf, utf_src, MAX_BUFSIZE); } } else { res = simple_recode (utf_str, "CP1251", "UTF-8", result_buf); if (!res) res = (char*)utf_str; } return res; }
/** * g_utf8_validate: * @str: a utf-8 encoded string * @max_len: max number of bytes to validate (or -1 to validate the entire null-terminated string) * @end: output parameter to mark the end of the valid input * * Checks @utf for being valid UTF-8. @str is assumed to be * null-terminated. This function is not super-strict, as it will * allow longer UTF-8 sequences than necessary. Note that Java is * capable of producing these sequences if provoked. Also note, this * routine checks for the 4-byte maximum size, but does not check for * 0x10ffff maximum value. * * Return value: %TRUE if @str is valid or %FALSE otherwise. **/ gboolean g_utf8_validate (const gchar *str, gssize max_len, const gchar **end) { guchar *inptr = (guchar *) str; gboolean valid = TRUE; guint length, min; gssize n = 0; if (max_len == 0) return FALSE; if (max_len < 0) { while (*inptr != 0) { length = g_utf8_jump_table[*inptr]; if (!utf8_validate (inptr, length)) { valid = FALSE; break; } inptr += length; } } else { while (n < max_len) { if (*inptr == 0) { /* Note: return FALSE if we encounter nul-byte * before max_len is reached. */ valid = FALSE; break; } length = g_utf8_jump_table[*inptr]; min = MIN (length, max_len - n); if (!utf8_validate (inptr, min)) { valid = FALSE; break; } if (min < length) { valid = FALSE; break; } inptr += length; n += length; } } if (end != NULL) *end = (gchar *) inptr; return valid; }
gunichar g_utf8_get_char_validated (const gchar *str, gssize max_len) { unsigned char *inptr = (unsigned char *) str; gunichar u = *inptr; int n, i; if (max_len == 0) return -2; if (u < 0x80) { /* simple ascii case */ return u; } else if (u < 0xc2) { return -1; } else if (u < 0xe0) { u &= 0x1f; n = 2; } else if (u < 0xf0) { u &= 0x0f; n = 3; } else if (u < 0xf8) { u &= 0x07; n = 4; } else if (u < 0xfc) { u &= 0x03; n = 5; } else if (u < 0xfe) { u &= 0x01; n = 6; } else { return -1; } if (max_len > 0) { if (!utf8_validate (inptr, MIN (max_len, n))) return -1; if (max_len < n) return -2; } else { if (!utf8_validate (inptr, n)) return -1; } for (i = 1; i < n; i++) u = (u << 6) | (*++inptr ^ 0x80); return u; }
static void add_tag(vorbis_comment *vc, oe_options *opt,char *name, char *value) { char *utf8; if (opt->isutf8) { if (!utf8_validate(value)) { fprintf(stderr, _("'%s' is not valid UTF-8, cannot add\n"), name?name:"comment"); } else { if(name == NULL) { vorbis_comment_add(vc, value); } else { vorbis_comment_add_tag(vc, name, value); } } } else if(utf8_encode(value, &utf8) >= 0) { if(name == NULL) { vorbis_comment_add(vc, utf8); } else { vorbis_comment_add_tag(vc, name, utf8); } free(utf8); } else { fprintf(stderr, _("Couldn't convert comment to UTF-8, cannot add\n")); } }
char* pa_utf8_filter (const char *str) { char *new_str; pa_assert(str); new_str = pa_xmalloc(strlen(str) + 1); return utf8_validate(str, new_str); }
std::string parseDisplayName(const pjsip_name_addr* sip_name_addr) { if (not sip_name_addr->display.ptr or not sip_name_addr->display.slen) return {}; std::string displayName {sip_name_addr->display.ptr, static_cast<size_t>(sip_name_addr->display.slen)}; // Filter out invalid UTF-8 characters to avoid getting kicked from D-Bus if (not utf8_validate(displayName)) return utf8_make_valid(displayName); return displayName; }
static inline int enc_string(Encoder* e, ERL_NIF_TERM val) { ErlNifBinary bin; char atom[512]; unsigned char* data; size_t size; int esc_extra = 0; int ulen; int uval; int i; if(enif_is_binary(e->env, val)) { if(!enif_inspect_binary(e->env, val, &bin)) { return 0; } data = bin.data; size = bin.size; } else if(enif_is_atom(e->env, val)) { if(!enif_get_atom(e->env, val, atom, 512, ERL_NIF_LATIN1)) { return 0; } data = (unsigned char*) atom; size = strlen(atom); } else { return 0; } i = 0; while(i < size) { switch((char) data[i]) { case '\"': case '\\': case '\b': case '\f': case '\n': case '\r': case '\t': esc_extra += 1; i++; continue; default: if(data[i] < 0x20) { esc_extra += 5; i++; continue; } else if(data[i] < 0x80) { i++; continue; } ulen = utf8_validate(&(data[i]), size - i); if(ulen < 0) { return 0; } if(e->uescape) { uval = utf8_to_unicode(&(data[i]), ulen); if(uval < 0) { return 0; } esc_extra += utf8_esc_len(uval); if(ulen < 0) { return 0; } } i += ulen; } } if(!enc_ensure(e, size + esc_extra + 2)) { return 0; } e->p[e->i++] = '\"'; i = 0; while(i < size) { switch((char) data[i]) { case '\"': case '\\': e->p[e->i++] = '\\'; e->u[e->i++] = data[i]; i++; continue; case '\b': e->p[e->i++] = '\\'; e->p[e->i++] = 'b'; i++; continue; case '\f': e->p[e->i++] = '\\'; e->p[e->i++] = 'f'; i++; continue; case '\n': e->p[e->i++] = '\\'; e->p[e->i++] = 'n'; i++; continue; case '\r': e->p[e->i++] = '\\'; e->p[e->i++] = 'r'; i++; continue; case '\t': e->p[e->i++] = '\\'; e->p[e->i++] = 't'; i++; continue; default: if(data[i] < 0x20) { ulen = unicode_uescape(data[i], &(e->p[e->i])); if(ulen < 0) { return 0; } e->i += ulen; i++; } else if((data[i] & 0x80) && e->uescape) { uval = utf8_to_unicode(&(data[i]), size-i); if(uval < 0) { return 0; } ulen = unicode_uescape(uval, &(e->p[e->i])); if(ulen < 0) { return 0; } e->i += ulen; ulen = utf8_len(uval); if(ulen < 0) { return 0; } i += ulen; } else { e->u[e->i++] = data[i++]; } } } e->p[e->i++] = '\"'; e->count++; return 1; }
char* pa_utf8_valid (const char *str) { return utf8_validate(str, NULL); }
int main(void) { int trial; plan_tests(TRIAL_COUNT); for (trial = 1; trial <= TRIAL_COUNT; trial++) { int i, count; uchar_t codepoints[MAX_CHARS_PER_TRIAL]; uchar_t c; bool c_valid; char write_buffer[MAX_CHARS_PER_TRIAL * 4]; char *o = write_buffer; char *oe = write_buffer + sizeof(write_buffer); char *string; const char *s; const char *e; int len; count = rand32() % MAX_CHARS_PER_TRIAL + 1; for (i = 0; i < count; i++) { if (o >= oe) { fail("utf8_write_char: Buffer overflow (1)"); goto next_trial; } switch (rand32() % 7) { case 0: c = range(rand32(), 0x0, 0x7F); c_valid = true; break; case 1: c = range(rand32(), 0x80, 0x7FF); c_valid = true; break; case 2: c = range(rand32(), 0x800, 0xD7FF); c_valid = true; break; case 3: c = range(rand32(), 0xD800, 0xDFFF); c_valid = false; break; case 4: c = range(rand32(), 0xE000, 0xFFFF); c_valid = true; break; case 5: c = range(rand32(), 0x10000, 0x10FFFF); c_valid = true; break; default: do { c = rand32(); } while (c < 0x110000); c_valid = false; break; } codepoints[i] = c_valid ? c : REPLACEMENT_CHARACTER; len = utf8_write_char(c, o); if (len < 1 || len > 4) { fail("utf8_write_char: Return value is not 1 thru 4."); goto next_trial; } o += len; } if (o > oe) { fail("utf8_write_char: Buffer overflow (2)"); goto next_trial; } string = malloc(o - write_buffer); memcpy(string, write_buffer, o - write_buffer); s = string; e = string + (o - write_buffer); if (!utf8_validate(s, e - s)) { fail("Invalid string produced by utf8_write_char."); goto next_trial_free_string; } for (i = 0; i < count; i++) { if (s >= e) { fail("utf8_read_char: Buffer overflow (1)"); goto next_trial_free_string; } len = utf8_read_char(s, &c); if (len < 1 || len > 4) { fail("utf8_read_char: Return value is not 1 thru 4."); goto next_trial_free_string; } if (c != codepoints[i]) { fail("utf8_read_char: Character read differs from that written."); goto next_trial_free_string; } s += len; } if (s > e) { fail("utf8_read_char: Buffer overflow (2)"); goto next_trial_free_string; } if (s < e) { fail("utf8_read_char: Did not reach end of string."); goto next_trial_free_string; } pass("Trial %d: %d characters", trial, count); next_trial_free_string: free(string); next_trial:; } return exit_status(); }
int dec_string(Decoder* d, ERL_NIF_TERM* value) { int has_escape = 0; int num_escapes = 0; int st; int ulen; int ui; int hi; int lo; char* chrbuf; int chrpos; if(d->p[d->i] != '\"') { return 0; } d->i++; st = d->i; while(d->i < d->len) { if(d->u[d->i] < 0x20) { return 0; } else if(d->p[d->i] == '\"') { d->i++; goto parse; } else if(d->p[d->i] == '\\') { if(d->i+1 >= d->len) { return 0; } has_escape = 1; num_escapes += 1; d->i++; switch(d->p[d->i]) { case '\"': case '\\': case '/': case 'b': case 'f': case 'n': case 'r': case 't': d->i++; break; case 'u': hi = 0; lo = 0; d->i++; if(d->i + 4 >= d->len) { return 0; } hi = int_from_hex(&(d->u[d->i])); if(hi < 0) { return 0; } d->i += 4; if(hi >= 0xD800 && hi < 0xDC00) { if(d->i + 6 >= d->len) { return 0; } if(d->p[d->i++] != '\\') { return 0; } else if(d->p[d->i++] != 'u') { return 0; } lo = int_from_hex(&(d->u[d->i])); if(lo < 0) { return 0; } hi = unicode_from_pair(hi, lo); if(hi < 0) { return 0; } } hi = utf8_len(hi); if(hi < 0) { return 0; } if(lo == 0) { num_escapes += 5 - hi; } else { num_escapes += 11 - hi; } break; default: return 0; } } else if(d->u[d->i] < 0x80) { d->i++; } else { ulen = utf8_validate(&(d->u[d->i]), d->len - d->i); if(ulen < 0) { return 0; } d->i += ulen; } } // The goto above ensures that we only // hit this when a string is not terminated // correctly. return 0; parse: if(!has_escape) { *value = enif_make_sub_binary(d->env, d->arg, st, (d->i - st - 1)); return 1; } hi = 0; lo = 0; ulen = (d->i - 1) - st - num_escapes; chrbuf = (char*) enif_make_new_binary(d->env, ulen, value); chrpos = 0; ui = st; while(ui < d->i - 1) { if(d->p[ui] != '\\') { chrbuf[chrpos++] = d->p[ui++]; continue; } ui++; switch(d->p[ui]) { case '\"': case '\\': case '/': chrbuf[chrpos++] = d->p[ui]; ui++; break; case 'b': chrbuf[chrpos++] = '\b'; ui++; break; case 'f': chrbuf[chrpos++] = '\f'; ui++; break; case 'n': chrbuf[chrpos++] = '\n'; ui++; break; case 'r': chrbuf[chrpos++] = '\r'; ui++; break; case 't': chrbuf[chrpos++] = '\t'; ui++; break; case 'u': ui++; hi = int_from_hex(&(d->u[ui])); if(hi < 0) { return 0; } if(hi >= 0xD800 && hi < 0xDC00) { lo = int_from_hex(&(d->u[ui+6])); if(lo < 0) { return 0; } hi = unicode_from_pair(hi, lo); ui += 10; } else { ui += 4; } hi = unicode_to_utf8(hi, (unsigned char*) chrbuf+chrpos); if(hi < 0) { return 0; } chrpos += hi; break; default: return 0; } } return 1; }
gpgme_error_t seahorse_passphrase_get (gconstpointer dummy, const gchar *passphrase_hint, const char* passphrase_info, int flags, int fd) { gchar **split_uid = NULL; gchar *label = NULL; gchar *errmsg = NULL; const gchar *pass; GcrPrompt *prompt; SyncClosure sync; GError *error = NULL; gchar *msg; sync.result = NULL; sync.loop = g_main_loop_new (NULL, FALSE); gcr_system_prompt_open_async (-1, NULL, on_sync_complete, &sync); g_main_loop_run (sync.loop); g_assert (sync.result != NULL); prompt = gcr_system_prompt_open_finish (sync.result, &error); g_main_loop_unref (sync.loop); g_object_unref (sync.result); if (error != NULL) { g_message ("Couldn't open system prompt: %s", error->message); g_error_free (error); return gpgme_error (GPG_ERR_CANCELED); } if (passphrase_info && strlen(passphrase_info) < 16) flags |= SEAHORSE_PASS_NEW; if (passphrase_hint) split_uid = g_strsplit (passphrase_hint, " ", 2); if (flags & SEAHORSE_PASS_BAD) errmsg = g_strdup_printf (_("Wrong passphrase.")); if (split_uid && split_uid[0] && split_uid[1]) { if (flags & SEAHORSE_PASS_NEW) label = g_strdup_printf (_("Enter new passphrase for ā%sā"), split_uid[1]); else label = g_strdup_printf (_("Enter passphrase for ā%sā"), split_uid[1]); } else { if (flags & SEAHORSE_PASS_NEW) label = g_strdup (_("Enter new passphrase")); else label = g_strdup (_("Enter passphrase")); } g_strfreev (split_uid); gcr_prompt_set_message (prompt, _("Passphrase")); msg = utf8_validate (errmsg ? errmsg : label); gcr_prompt_set_description (prompt, msg); g_free (msg); gcr_prompt_set_password_new (prompt, flags & SEAHORSE_PASS_NEW); gcr_prompt_set_continue_label (prompt, _("OK")); gcr_prompt_set_cancel_label (prompt, _("Cancel")); g_free (label); g_free (errmsg); pass = gcr_prompt_password_run (prompt, NULL, &error); if (pass != NULL) seahorse_util_printf_fd (fd, "%s\n", pass); gcr_system_prompt_close_async (GCR_SYSTEM_PROMPT (prompt), NULL, NULL, NULL); g_object_unref (prompt); if (error != NULL) { g_message ("Couldn't prompt for password: %s", error->message); g_error_free (error); return gpgme_error (GPG_ERR_CANCELED); } return 0; }
GtkDialog* seahorse_passphrase_prompt_show (const gchar *title, const gchar *description, const gchar *prompt, const gchar *check, gboolean confirm) { GtkEntryBuffer *buffer; GtkEntry *entry; GtkDialog *dialog; GtkWidget *w; GtkWidget *box; GtkTable *table; GtkWidget *wvbox; GtkWidget *chbox; gchar *msg; if (!title) title = _("Passphrase"); if (!prompt) prompt = _("Password:"******"size-request", G_CALLBACK (constrain_size), NULL); g_signal_connect (G_OBJECT (dialog), "map-event", G_CALLBACK (grab_keyboard), NULL); g_signal_connect (G_OBJECT (dialog), "unmap-event", G_CALLBACK (ungrab_keyboard), NULL); g_signal_connect (G_OBJECT (dialog), "window-state-event", G_CALLBACK (window_state_changed), NULL); wvbox = gtk_vbox_new (FALSE, HIG_LARGE * 2); gtk_container_add (GTK_CONTAINER (gtk_dialog_get_content_area (dialog)), wvbox); gtk_container_set_border_width (GTK_CONTAINER (wvbox), HIG_LARGE); chbox = gtk_hbox_new (FALSE, HIG_LARGE); gtk_box_pack_start (GTK_BOX (wvbox), chbox, FALSE, FALSE, 0); /* The image */ w = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG); gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.0); gtk_box_pack_start (GTK_BOX (chbox), w, FALSE, FALSE, 0); box = gtk_vbox_new (FALSE, HIG_SMALL); gtk_box_pack_start (GTK_BOX (chbox), box, TRUE, TRUE, 0); /* The description text */ if (description) { msg = utf8_validate (description); w = gtk_label_new (msg); g_free (msg); gtk_misc_set_alignment (GTK_MISC (w), 0.0, 0.5); gtk_label_set_line_wrap (GTK_LABEL (w), TRUE); gtk_box_pack_start (GTK_BOX (box), w, TRUE, FALSE, 0); } /* Two entries (usually on is hidden) in a vbox */ table = GTK_TABLE (gtk_table_new (3, 2, FALSE)); gtk_table_set_row_spacings (table, HIG_SMALL); gtk_table_set_col_spacings (table, HIG_LARGE); gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (table), FALSE, FALSE, 0); /* The first entry if we have one */ if (confirm) { msg = utf8_validate (prompt); w = gtk_label_new (msg); g_free (msg); gtk_table_attach (table, w, 0, 1, 0, 1, GTK_FILL, 0, 0, 0); buffer = seahorse_secure_buffer_new (); entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer)); g_object_unref (buffer); gtk_entry_set_visibility (entry, FALSE); gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1); g_object_set_data (G_OBJECT (dialog), "confirm-entry", entry); g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (confirm_callback), dialog); g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (entry_changed), dialog); gtk_table_attach_defaults (table, GTK_WIDGET (entry), 1, 2, 0, 1); gtk_widget_grab_focus (GTK_WIDGET (entry)); } /* The second and main entry */ msg = utf8_validate (confirm ? _("Confirm:") : prompt); w = gtk_label_new (msg); g_free (msg); gtk_table_attach (table, w, 0, 1, 1, 2, GTK_FILL, 0, 0, 0); buffer = seahorse_secure_buffer_new (); entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer)); g_object_unref (buffer); gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1); gtk_entry_set_visibility (entry, FALSE); g_object_set_data (G_OBJECT (dialog), "secure-entry", entry); g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (enter_callback), dialog); gtk_table_attach_defaults (table, GTK_WIDGET (entry), 1, 2, 1, 2); if (!confirm) gtk_widget_grab_focus (GTK_WIDGET (entry)); else g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (entry_changed), dialog); /* The checkbox */ if (check) { w = gtk_check_button_new_with_mnemonic (check); gtk_table_attach_defaults (table, w, 1, 2, 2, 3); g_object_set_data (G_OBJECT (dialog), "check-option", w); } gtk_widget_show_all (GTK_WIDGET (table)); w = gtk_button_new_from_stock (GTK_STOCK_CANCEL); gtk_dialog_add_action_widget (dialog, w, GTK_RESPONSE_REJECT); gtk_widget_set_can_default (w, TRUE); w = gtk_button_new_from_stock (GTK_STOCK_OK); gtk_dialog_add_action_widget (dialog, w, GTK_RESPONSE_ACCEPT); gtk_widget_set_can_default (w, TRUE); g_signal_connect_object (G_OBJECT (entry), "focus_in_event", G_CALLBACK (gtk_widget_grab_default), G_OBJECT (w), 0); gtk_widget_grab_default (w); g_signal_connect (dialog, "key_press_event", G_CALLBACK (key_press), NULL); gtk_window_set_position (GTK_WINDOW (dialog), GTK_WIN_POS_CENTER); gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE); gtk_window_set_type_hint (GTK_WINDOW (dialog), GDK_WINDOW_TYPE_HINT_NORMAL); gtk_window_set_keep_above (GTK_WINDOW (dialog), TRUE); gtk_widget_show_all (GTK_WIDGET (dialog)); gdk_window_focus (gtk_widget_get_window (GTK_WIDGET (dialog)), GDK_CURRENT_TIME); if (confirm) entry_changed (NULL, dialog); return dialog; }