int main() { char *dec; unsigned i; unsigned len; for (i=0;i<sizeof(encoded_strings)/sizeof(encoded_strings[0]);i++) { dec = unescape_html(NULL, encoded_strings[i], strlen(encoded_strings[i]), &len); if (dec == NULL) { fprintf(stderr, "failed to unescape %s\n", encoded_strings[i]); exit(1); } if (strcmp(dec, strings[i]) != 0) { fprintf(stderr, "string %d, fails decoding:\n\tinput: '%s'\n\toutput: '%s'\n", i, strings[i], dec); exit(1); } talloc_free(dec); } return 0; }
static VALUE rb_unescape_html(VALUE self, VALUE str) { Check_Type(str, T_STRING); VALUE rb_output_buf; unsigned char *inBuf = (unsigned char*)RSTRING_PTR(str); size_t len = RSTRING_LEN(str), new_len = 0; // this is the max size the string could be // TODO: we should try to be more intelligent about this unsigned char *outBuf = (unsigned char *)malloc(sizeof(unsigned char *)*len); // perform our escape, returning the new string's length new_len = unescape_html(outBuf, inBuf, len); // create our new ruby string rb_output_buf = rb_str_new((char *)outBuf, new_len); // free the temporary C string free(outBuf); return rb_output_buf; }
/* Returns the contents of the provided fields in a newly allocated * string, or a negative value on error. * * @body: is the string to search the xml field at, should be null-terminated. * @xml_field: the XML field to check for (e.g., MYFIELD) * @value: the value that was found */ static int parse_reply(worker_st * ws, char *body, unsigned body_length, const char *field, unsigned field_size, const char *xml_field, unsigned xml_field_size, char **value) { char *p; char temp1[64]; char temp2[64]; unsigned temp2_len, temp1_len; unsigned len, xml = 0; if (body == NULL || body_length == 0) return -1; if (memmem(body, body_length, "<?xml", 5) != 0) { xml = 1; if (xml_field) { field = xml_field; field_size = xml_field_size; } snprintf(temp1, sizeof(temp1), "<%s>", field); snprintf(temp2, sizeof(temp2), "</%s>", field); temp1_len = strlen(temp1); temp2_len = strlen(temp2); /* body should contain <field>test</field> */ *value = strcasestr(body, temp1); if (*value == NULL) { oclog(ws, LOG_HTTP_DEBUG, "cannot find '%s' in client XML message", field); return -1; } *value += temp1_len; p = *value; len = 0; while (*p != 0) { if (*p == '<' && (strncasecmp(p, temp2, temp2_len) == 0)) { break; } p++; len++; } } else { /* non-xml version */ snprintf(temp1, sizeof(temp1), "%s=", field); temp1_len = strlen(temp1); /* body should be "username=test&password=test" */ *value = strcasestr(body, temp1); if (*value == NULL) { oclog(ws, LOG_HTTP_DEBUG, "cannot find '%s' in client message", field); return -1; } *value += temp1_len; p = *value; len = 0; while (*p != 0) { if (*p == '&') { break; } p++; len++; } } if (len == 0) { *value = talloc_strdup(ws->req.body, ""); if (*value != NULL) return 0; return -1; } if (xml) *value = unescape_html(ws->req.body, *value, len, NULL); else *value = unescape_url(ws->req.body, *value, len, NULL); if (*value == NULL) { oclog(ws, LOG_ERR, "%s requested but no such field in client message", field); return -1; } return 0; }
/* * The almighty html parser method */ void parse_html(GtkTextView *text_view, GtkTextMark html_start, int ignore) { GtkTextBuffer *html_buffer = gtk_text_view_get_buffer(text_view); tag *last_tag; GList *tag_list = NULL; int tagid = 0; GtkTextIter start_iter, end_iter; GtkTextMark *end_mark; GtkTextIter tag_start_iter, tag_end_iter; gtk_text_buffer_get_iter_at_mark(html_buffer, &start_iter, &html_start); gtk_text_buffer_get_end_iter(html_buffer, &end_iter); end_mark = gtk_text_buffer_create_mark(html_buffer, NULL, &end_iter, TRUE); gtk_text_buffer_get_iter_at_mark(html_buffer, &tag_start_iter, &html_start); gtk_text_buffer_get_iter_at_mark(html_buffer, &tag_end_iter, &html_start); /* Check if < and > exist in that order */ while (search_char(&tag_start_iter, '<') && search_char(&tag_end_iter, '>')) { gchar *tag_string; GtkTextMark *tag_start_mark = NULL, *next_start_mark = NULL; if (gtk_text_iter_compare(&tag_start_iter, &tag_end_iter) > 0) { gtk_text_iter_forward_char(&tag_end_iter); tag_start_iter = tag_end_iter; continue; } gtk_text_iter_forward_char(&tag_end_iter); tag_start_mark = gtk_text_buffer_create_mark(html_buffer, NULL, &tag_start_iter, TRUE); next_start_mark = gtk_text_buffer_create_mark(html_buffer, NULL, &tag_end_iter, TRUE); tag_string = gtk_text_buffer_get_slice(html_buffer, &tag_start_iter, &tag_end_iter, TRUE); /* Get rid of the < and > and clean up the tag string */ tag_string = strstr(tag_string, "<") + 1; if (tag_string && strstr(tag_string, ">")) *(strstr(tag_string, ">")) = '\0'; g_strstrip(tag_string); if (*tag_string == '/' && tag_is_valid(++tag_string)) { int found_match = 0; last_tag = NULL; /* Now get rid of the tag from the text */ gtk_text_buffer_delete(html_buffer, &tag_start_iter, &tag_end_iter); /* * This is an end tag. So now we must apply the tag to * the enclosed text */ do { last_tag = g_list_nth_data(g_list_last(tag_list), 0); if (last_tag == NULL) break; if (!g_ascii_strncasecmp(tag_string, last_tag->name, strlen(tag_string))) { last_tag->end = *tag_start_mark; found_match = 1; } else { last_tag->end = *end_mark; } apply_tag(text_view, *last_tag, ignore); tag_list = g_list_remove(tag_list, last_tag); } while (!found_match); } else if (tag_is_valid(tag_string)) { tag *cur; /* Now get rid of the tag from the text */ gtk_text_buffer_delete(html_buffer, &tag_start_iter, &tag_end_iter); /* This is a start tag. So put this into the list */ cur = (tag *)malloc(sizeof(tag)); bzero(cur->id, 8); sprintf(cur->id, "%d%d", messageid, tagid++); cur->name = strdup(tag_string); cur->start = *tag_start_mark; /* * Insert into the tag list only if it's a * closing type tag */ if (!(ay_strcasestr(tag_string, "smiley") == tag_string || ay_strcasestr(tag_string, "br") == tag_string || ay_strcasestr(tag_string, "img") == tag_string || ay_strcasestr(tag_string, "hr") == tag_string)) { tag_list = g_list_append(tag_list, cur); } else { apply_tag(text_view, *cur, ignore); free(cur); } } /* Re-initialize the string to get new positions */ gtk_text_buffer_get_end_iter(html_buffer, &end_iter); end_mark = gtk_text_buffer_create_mark(html_buffer, NULL, &end_iter, TRUE); gtk_text_buffer_get_iter_at_mark(html_buffer, &tag_start_iter, next_start_mark); gtk_text_buffer_get_iter_at_mark(html_buffer, &tag_end_iter, next_start_mark); } while ((last_tag = g_list_nth_data(g_list_last(tag_list), 0))) { last_tag->end = *end_mark; apply_tag(text_view, *last_tag, ignore); tag_list = g_list_remove(tag_list, last_tag); } g_list_free(tag_list); unescape_html(html_buffer, html_start); messageid++; }
/* Returns the contents of the password field in a newly allocated * string, or a negative value on error. * * @body: is the string to search the xml field at, should be null-terminated. * @value: the value that was found */ static int match_password_in_reply(worker_st * ws, char *body, unsigned body_length, char **value) { char *p; unsigned len, xml = 0; if (body == NULL || body_length == 0) return -1; if (memmem(body, body_length, "<?xml", 5) != 0) { xml = 1; /* body should contain <password?>test</password?> */ *value = strcasestr(body, "<password"); if (*value == NULL) { oclog(ws, LOG_HTTP_DEBUG, "cannot find password in client XML message"); return -1; } /* find terminator */ p = strchr(*value, '>'); if (p == NULL) { oclog(ws, LOG_HTTP_DEBUG, "unterminated password in client XML message"); return -1; } p++; *value = p; len = 0; while (*p != 0) { if (*p == '<' && (strncasecmp(p, "</password", sizeof("</password")-1) == 0)) { break; } p++; len++; } } else { /* non-xml version */ /* body should be "username=test&password?=test" */ *value = strcasestr(body, "password"); if (*value == NULL) { oclog(ws, LOG_HTTP_DEBUG, "cannot find password in client message"); return -1; } p = strchr(*value, '='); if (p == NULL) { oclog(ws, LOG_HTTP_DEBUG, "unterminated password in client message"); return -1; } p++; *value = p; len = 0; while (*p != 0) { if (*p == '&') { break; } p++; len++; } } if (len == 0) { *value = talloc_strdup(ws->req.body, ""); if (*value != NULL) return 0; return -1; } if (xml) *value = unescape_html(ws->req.body, *value, len, NULL); else *value = unescape_url(ws->req.body, *value, len, NULL); if (*value == NULL) { oclog(ws, LOG_ERR, "password requested but no such field in client message"); return -1; } return 0; }