xupl* xupl_parse(xupl *xup) { xupl_*_ = (xupl_*) xup; FILE* in = _->in; off_t buffsize = _->buffsize; unsigned short bit = 0x0001; unsigned short WHITESPACE = bit; unsigned short DOUBLE_STRING = (bit <<= 1); unsigned short SINGLE_STRING = (bit <<= 1); unsigned short STRING = DOUBLE_STRING | SINGLE_STRING; unsigned short LINE_COMMENT = (bit <<= 1); unsigned short MULTI_COMMENT = (bit <<= 1); unsigned short COMMENT = LINE_COMMENT | MULTI_COMMENT; unsigned short _state = 0; const int default_tksize = 12; int tksize = default_tksize + 1; unsigned char *tk = NULL; int tkndx = 0; int chars_read; char* buf = malloc(buffsize + 1); xmlNodePtr xroot = NULL; xmlNodePtr xc = NULL; xmlAttrPtr xprop = NULL; const xmlChar* xuplAttr = (const xmlChar*) "data-xupl"; const xmlChar* xuplClosed = (const xmlChar*) "closed"; xmlDocPtr xdoc = xmlNewDoc((const unsigned char*) "1.1"); //xmlNsPtr xuplNs = xmlNewGlobalNs(xdoc,"http://ns.xupl.org/1.1","xupl"); while ((chars_read = fread(buf, 1, buffsize, in)) > 0) { for (int i = 0; i < chars_read; i++) { const char c = buf[i]; switch (c) { case '\'': case '"': IF(COMMENT) break; IF(STR(c)) { DISABLE(STR(c)); } else if (NOT(STRING)) { ALLOW(STR(c)); break; } case '{': case '}': case ' ': case '\n': case '\r': case '\t': case '\f': case '\v': case ',': case '=': // Comment characters case '*': case '/': case '#': case '!': IF(STRING) break; switch (c) { case ',': case '{': xprop = NULL; } if (tk) { tk[tkndx] = 0; char p = 0; if (tkndx >= 1) p = tk[tkndx - 1]; unsigned char* m = NULL; unsigned int tklen = tkndx + 1; unsigned char* t = tk; IF(COMMENT) { if ('\n' == c && IS(LINE_COMMENT)) { if (tkndx + 1 < tksize) { tk[tkndx++] = ' '; tk[tkndx] = 0; } } else if ('*' == p && '/' == c && IS(MULTI_COMMENT)) { tk[tkndx - 1] = 0; } else break; DISABLE(COMMENT); m = tk + 2; } else if ('/' == p && '*' == c) { ALLOW(MULTI_COMMENT); break; // Single-line comments can be #! #* #/ ## } else if ('#' == p && ('!' == c || '*' == c || '/' == c || '#' == c)) { ALLOW(LINE_COMMENT); break; // If these characters were in the token and not part of a comment, // then continue as if they are normal characters of a token. } else if ('!' == c || '/' == c || '*' == c || '#' == c) break; if (!xc) { if (m) { xroot = xmlNewDocComment(xdoc, m); xmlDocSetRootElement(xdoc, xroot); } else { xc = xmlNewNode(NULL, tk); xmlDocSetRootElement(xdoc, xc); if (!xroot) xroot = xc; } } else if (m) { xmlAddChild(xc, xmlNewComment(m)); } else { char *attr = NULL; xmlAttrPtr closed = xmlHasProp(xc, xuplAttr); switch (tk[0]) { case '\'': case '"': t += 1; xmlAddChild(xc, xmlNewText(t)); break; // TODO make this parameterized, characters and names. case '.': attr = "class"; break; case '#': attr = "id"; break; case '@': attr = "project"; break; case '/': attr = "href"; break; case '[': attr = "data"; break; case '~': attr = "duration"; break; case '=': attr = "location"; break; case '^': attr = "at"; break; case ':': attr = "type"; break; case '!': attr = "priority"; break; default: { regmatch_t pmatch[1]; unsigned int isword = 0 == regexec(&re_word, (char*) tk, 1, pmatch, 0); if (closed) { if (isword) { xc = xmlNewChild(xc, NULL, tk, NULL); } else { xmlAddChild(xc, xmlNewText(tk)); } } else { if (xprop) { xmlNewProp(xc, xprop->name, tk); xmlRemoveProp(xprop); xprop = NULL; } else if (isword) { xprop = xmlNewProp(xc, tk, (unsigned char*) "True"); } else { xprop = xmlNewProp(xc, (unsigned char*) ".fake", tk); } switch (c) { case ',': case '{': xprop = NULL; } } } break; } if (attr) { if (closed) { xmlAddChild(xc, xmlNewText(t)); } else { xmlNewProp(xc, (xmlChar*) attr, t); } } } free(tk); tk = NULL; if (tksize > default_tksize && tkndx < default_tksize) { tksize /= 2; } tkndx = 0; if (m) continue; } default: break; } switch (c) { case '{': xmlNewProp(xc, xuplAttr, xuplClosed); continue; case '}': if (xc) { xmlAttrPtr data = xmlHasProp(xc, xuplAttr); if (data) xmlRemoveProp(data); xc = xc->parent; } continue; default: break; } // Accumulate the tk. if (!tk || tkndx >= tksize) { // If the tk buffer is too small, double it. tk = realloc(tk, tksize *= 2); } tk[tkndx++] = c; }
static void set_filters() { struct sock_filter filter[] = { VALIDATE_ARCHITECTURE, EXAMINE_SYSCALL, ALLOW_SYSCALL(rt_sigreturn), ALLOW_SYSCALL(exit_group), ALLOW_SYSCALL(exit), ALLOW_SYSCALL(read), ALLOW_SYSCALL(write), ALLOW_SYSCALL(fstat), ALLOW_SYSCALL(mmap), ALLOW_SYSCALL(rt_sigaction), ALLOW_SYSCALL(rt_sigprocmask), ALLOW_SYSCALL(clone), ALLOW_SYSCALL(execve), ALLOW(20), ALLOW(12), ALLOW(21), ALLOW(2), ALLOW(4), ALLOW(3), ALLOW(10), ALLOW(158), ALLOW(11), ALLOW(61), ALLOW(16), KILL_PROCESS, }; struct sock_fprog prog = { sizeof(filter) / sizeof(filter[0]), filter }; int ret=0; ret = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); assert(!ret); ret = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog); assert(!ret); }