in libmbfl/filters/mbfilter_htmlent.c [180:287]
int mbfl_filt_conv_html_dec(int c, mbfl_convert_filter *filter)
{
int pos, ent = 0;
mbfl_html_entity_entry *entity;
char *buffer = (char*)filter->opaque;
if (!filter->status) {
if (c == '&' ) {
filter->status = 1;
buffer[0] = '&';
} else {
CK((*filter->output_function)(c, filter->data));
}
} else {
if (c == ';') {
if (buffer[1]=='#') {
if (filter->status > 2 && (buffer[2] == 'x' || buffer[2] == 'X')) {
if (filter->status > 3) {
/* numeric entity */
for (pos=3; pos<filter->status; pos++) {
int v = buffer[pos];
if (v >= '0' && v <= '9') {
v = v - '0';
} else if (v >= 'A' && v <= 'F') {
v = v - 'A' + 10;
} else if (v >= 'a' && v <= 'f') {
v = v - 'a' + 10;
} else {
ent = -1;
break;
}
ent = ent * 16 + v;
}
} else {
ent = -1;
}
} else {
/* numeric entity */
if (filter->status > 2) {
for (pos=2; pos<filter->status; pos++) {
int v = buffer[pos];
if (v >= '0' && v <= '9') {
v = v - '0';
} else {
ent = -1;
break;
}
ent = ent*10 + v;
}
} else {
ent = -1;
}
}
if (ent >= 0 && ent < 0x110000) {
CK((*filter->output_function)(ent, filter->data));
} else {
for (pos = 0; pos < filter->status; pos++) {
CK((*filter->output_function)(buffer[pos], filter->data));
}
CK((*filter->output_function)(c, filter->data));
}
filter->status = 0;
/*php_error_docref("ref.mbstring" TSRMLS_CC, E_NOTICE, "mbstring decoded '%s'=%d", buffer, ent);*/
} else {
/* named entity */
buffer[filter->status] = 0;
entity = (mbfl_html_entity_entry *)mbfl_html_entity_list;
while (entity->name) {
if (!strcmp(buffer+1, entity->name)) {
ent = entity->code;
break;
}
entity++;
}
if (ent) {
/* decoded */
CK((*filter->output_function)(ent, filter->data));
filter->status = 0;
/*php_error_docref("ref.mbstring" TSRMLS_CC, E_NOTICE,"mbstring decoded '%s'=%d", buffer, ent);*/
} else {
/* failure */
buffer[filter->status++] = ';';
buffer[filter->status] = 0;
/* php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring cannot decode '%s'", buffer); */
mbfl_filt_conv_html_dec_flush(filter);
}
}
} else {
/* add character */
buffer[filter->status++] = c;
/* add character and check */
if (!strchr(html_entity_chars, c) || filter->status+1==html_enc_buffer_size || (c=='#' && filter->status>2))
{
/* illegal character or end of buffer */
if (c=='&')
filter->status--;
buffer[filter->status] = 0;
/* php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring cannot decode '%s'", buffer)l */
mbfl_filt_conv_html_dec_flush(filter);
if (c=='&')
{
buffer[filter->status++] = '&';
}
}
}
}
return c;
}