PDF-Make
view release on metacpan or search on metacpan
src/pdfmake_markup.c view on Meta::CPAN
fail(s, line, col, "invalid UTF-8: truncated sequence");
return 0;
}
{
int i;
for (i = 1; i <= extra; i++) {
unsigned char cc = (unsigned char)p[i];
if ((cc & 0xC0) != 0x80) {
fail(s, line, col,
"invalid UTF-8: byte 0x%02X is not a continuation", cc);
return 0;
}
cp = (cp << 6) | (cc & 0x3Fu);
}
}
if ((extra == 1 && cp < 0x80) ||
(extra == 2 && cp < 0x800) ||
(extra == 3 && cp < 0x10000)) {
fail(s, line, col, "invalid UTF-8: overlong encoding");
return 0;
}
if (cp >= 0xD800 && cp <= 0xDFFF) {
fail(s, line, col, "invalid UTF-8: encoded surrogate U+%04lX",
(unsigned long)cp);
return 0;
}
if (cp > 0x10FFFF) {
fail(s, line, col, "invalid UTF-8: code point above U+10FFFF");
return 0;
}
p += extra + 1;
col++;
}
return 1;
}
pdfmake_markup_doc_t *pdfmake_markup_parse(const char *src, size_t len) {
pdfmake_markup_doc_t *doc;
scan_t s;
doc = (pdfmake_markup_doc_t *)calloc(1, sizeof(*doc));
if (!doc) return NULL;
doc->arena = pdfmake_arena_new();
if (!doc->arena) { free(doc); return NULL; }
doc->ok = 1;
if (!src) { src = ""; len = 0; }
s.p = src;
s.end = src + len;
s.line = 1;
s.col = 1;
s.doc = doc;
s.depth = 0;
if (!validate_utf8(&s, s.p, s.end)) return doc;
/* Skip a UTF-8 BOM: editors add it, and it is not the author's fault. */
if (len >= 3 && (unsigned char)src[0] == 0xEF &&
(unsigned char)src[1] == 0xBB && (unsigned char)src[2] == 0xBF) {
s.p += 3;
}
skip_space(&s);
while (!at_end(&s) && s.doc->ok && peek(&s) == '<' &&
peek_at(&s, 1) == '!' && peek_at(&s, 2) == '-') {
skip_comment(&s);
skip_space(&s);
}
if (at_end(&s)) {
if (doc->ok)
fail(&s, 1, 1, "empty document: expected <doc>");
return doc;
}
if (peek(&s) != '<') {
fail(&s, s.line, s.col, "text outside <doc>");
return doc;
}
{
/* The root must be <doc>. Checking here rather than in parse_element
* keeps the error specific: "expected <doc>" beats "unknown tag". */
const char *q = s.p + 1;
size_t qlen = 0;
while (q + qlen < s.end && is_name_char(q[qlen])) qlen++;
if (qlen != 3 || memcmp(q, "doc", 3) != 0) {
fail(&s, s.line, s.col,
"the root element must be <doc>, found '<%.*s>'",
(int)(qlen > 32 ? 32 : qlen), q);
return doc;
}
}
{
pdfmake_markup_node_t *holder =
node_new(&s, PDFMAKE_MARKUP_ELEM, 1, 1);
if (!holder) { fail(&s, 1, 1, "out of memory"); return doc; }
holder->tag = PDFMAKE_MK_INVALID;
parse_element(&s, holder);
if (doc->ok) doc->root = holder->first_child;
}
if (doc->ok) {
skip_space(&s);
while (!at_end(&s) && peek(&s) == '<' && peek_at(&s, 1) == '!' &&
peek_at(&s, 2) == '-') {
skip_comment(&s);
skip_space(&s);
}
if (!at_end(&s))
fail(&s, s.line, s.col, "content after </doc>");
}
return doc;
}
( run in 5.046 seconds using v1.01-cache-2.11-cpan-8dfa8b56332 )