static void check (const char *literal, int cflags, const char *expected) { struct regex_quote_spec spec; char *result; size_t length; spec = regex_quote_spec_posix (cflags, false); result = regex_quote (literal, &spec); ASSERT (strcmp (result, expected) == 0); length = regex_quote_length (literal, &spec); ASSERT (length == strlen (result)); free (result); result = (char *) xmalloc (1 + length + 1 + 1); result[0] = '^'; strcpy (regex_quote_copy (result + 1, literal, &spec), "$"); { regex_t regex; regmatch_t match[1]; ASSERT (regcomp (®ex, result, cflags) == 0); ASSERT (regexec (®ex, literal, 1, match, 0) == 0); ASSERT (match[0].rm_so == 0); ASSERT (match[0].rm_eo == strlen (literal)); regfree (®ex); } free (result); spec = regex_quote_spec_posix (cflags, true); result = regex_quote (literal, &spec); length = regex_quote_length (literal, &spec); ASSERT (length == strlen (result)); { regex_t regex; regmatch_t match[1]; ASSERT (regcomp (®ex, result, cflags) == 0); ASSERT (regexec (®ex, literal, 1, match, 0) == 0); ASSERT (match[0].rm_so == 0); ASSERT (match[0].rm_eo == strlen (literal)); regfree (®ex); } free (result); }
String IOMLCode::encodeBody(shared_ptr<OMLContext> context, const String& text, bool postProcess, bool preserveStartLineSpaces, bool convertCR) { String value = text; if ( (postProcess) && (context->getMode() != omlRenderModeSearch) && (!context->getRow()) ) { // Detect degli url { String protocolsFindLinkOption = context->getPage()->getOption(Options::url_options::protocols_find_link); //String protocolsFindLinkOption = Options::instance()->getOption(Options::url_options::protocols_find_link); //String UrlMatch = _S("(")+getProtocolsFindLinkOption()+_S(")://(\\w*:\\w*@)?[-\\w.]+(:\\d+)?(/([\\w/_.]*(\\?\\S+)?)?)?"); //String UrlMatch = _S("((")+getProtocolsFindLinkOption()+_S(")(\\W+\\S+[^).,:;?\\]\\} \\r\\n$]+))"); //String UrlMatch = _S("(")+protocolsFindLinkOption+_S(")://(\\w*:\\w*@)?[-\\w.]+(:\\d+)?(/([\\w/_.]*(\\?\\S+)?)?)?"); // 0.11: //String UrlMatch = _S("(") + protocolsFindLinkOption + _S(")://\\S+"); // 1.0: String UrlMatch = _S("(") + protocolsFindLinkOption + _S("):[/\?]\\S+"); // La versione sotto sarebbe meglio, ma non funziona, ad esempio con il link seguente: // skype:?chat&blob=iCnRW4EXR0H_funqp8i2FpbcobXxBfFkllPp0s2NMRd_sbDEOEr5Je-RzNUi //String UrlMatch = _S("(")+protocolsFindLinkOption+_S("):\\S+"); String UrlReplace = _S("[url]$0[/url]"); //if(regex_match(value, RegexManager::instance()->getRegex(UrlMatch, true))) value = regex_replace(value, RegexManager::instance()->getRegex(UrlMatch, true), UrlReplace); //String MailMatch = _S("\\b((([A-Za-z0-9$_.+%=-])|%[A-Fa-f0-9]{2})+@(([A-Za-z0-9$_.+!*,;/?:%&=-])|%[A-Fa-f0-9]{2})+\\.[a-zA-Z0-9]{1,4})"); String MailMatch = _S("(\\w+\\.)*\\w+@(\\w+\\.)+[A-Za-z]+"); String MailReplace = _S("[email]$0[/email]"); //if(regex_match(value, RegexManager::instance()->getRegex(MailMatch, true))) value = regex_replace(value, RegexManager::instance()->getRegex(MailMatch, true), MailReplace); } if(value != text) { // Sono stati inseriti tag, ricomputo... return encodeOML(context, value); } } // Risolvo gli escaping value.replace_all(_S("\\["), _S("[")); //value.replace_all(_S("\\]"), _S("]")); // Encoding html value = encode(context, value); if(postProcess) { // Emoticons if( (context->getMode() != omlRenderModeSearch) && (context->getPage() != nullptr) ) { String valueLower = value; valueLower.to_lower(); //const StringMap &emoticons = IdeSystem::instance()->getEmoticons(); //for(StringMap::const_iterator i = emoticons.begin(); i != emoticons.end(); ++i) const OMLManager::Emoticons &emoticons = OMLManager::instance()->getEmoticons(); for(OMLManager::Emoticons::const_iterator i = emoticons.begin(); i != emoticons.end(); ++i) { //const String &code = i->first; shared_ptr<OMLEmoticon> emo = *i; const String &code = emo->getCode(); // Ottimizzazione, se non lo trovo con una 'find' secca sull'equivalente in lower-case, // inutile cercarlo via regex. if(valueLower.find(emo->getCode()) != String::npos) { //const String &name = i->second; const String &name = emo->getName(); String title = getText(context, _S("emoticons.") + name); String url = context->getPage()->getSkin()->getImageUrl(_S("emoticons/")+name+_S(".gif")); String out = String::format(_S(" <img src=\"%S\" alt=\"%S\" title=\"%S\"> ").c_str(), url.c_str(), code.c_str(), title.c_str()); // Se prima o dopo non c' niente, o c' un carattere : String codeRegexQuote = regex_quote(code); // RegEx presa da Invision // $txt = preg_replace( "!(?<=[^\w&;/])$code(?=.\W|\W.|\W$)!ei", "\$this->convert_emoticon('$code', '$image')", $txt ); //String re = _S("!(?<=[^\\w&;/])") + codeRegexQuote + _S("(?=.\\W|\\W.|\\W$)!ei"); //String re = _S("( ")+codeRegexQuote+_S(" |^")+codeRegexQuote+_S(" | ")+codeRegexQuote+_S("$|^")+codeRegexQuote+_S("$)"); // Non sono riuscito a far e il detect dei limiti della stringa, per cui aggiungo due spazi prima e trimmo dopo. value = _S(" ") + value + _S(" "); //String charsEmoBoundary = _S("\\s\\n\\r:),;"); //String re = String::format(_S("(?<=[%S])%S(?=[%S])").c_str(), charsEmoBoundary.c_str(), codeRegexQuote.c_str(), charsEmoBoundary.c_str()); String re = String::format(_S("(?<=[\\s])%S(?=[\\s])").c_str(), codeRegexQuote.c_str()); // URGENT: da ottimizzare con una // shared_ptr<boost::wregex> re = regex_create(regex, nocase); value = regex_replace(value, RegexManager::instance()->getRegex(re, true), out); // Tolgo i due spazi messi sopra value = value.substr(1,value.length()-2); } } } } // Encoding dei \n if ( (context->getMode() == omlRenderModeSearch) || (context->getRow()) ) { value.replace_all(_S("\n"), _S(" ")); } else { if(preserveStartLineSpaces) { for(;;) { String::size_type posCR = value.find(_S("\n")); if(posCR == String::npos) break; String::size_type posFirstNoSpace = value.find_first_not_of(_S(" "), posCR+1); if(posFirstNoSpace == String::npos) posFirstNoSpace = value.length(); String startLineText = value.substr(posCR+1, posFirstNoSpace - (posCR+1)); startLineText.replace_all(_S(" "),_S(" ")); value = value.substr(0,posCR) + _S("<br>") + startLineText + value.substr(posFirstNoSpace); } } else if(convertCR) { value.replace_all(_S("\n"), _S("<br />")); } } // Ulteriore encoding finale di sicurezza XSS, trasformo i '\' in '\'. value.replace_all(_S("\\"),_S("\")); return value; }
int cmdSetPath(ClientData client_data, Tcl_Interp *interp, int argc, CONST84 char *argv[]) { Tcl_RegExp chkexpPtr; /** Regular expression for * marker checking **/ char *oldpath, /** Old value of 'var' **/ *newpath, /** New value of 'var' **/ *sw_marker = APP_SW_MARKER, /** arbitrary default **/ *startp = NULL, *endp = NULL, /** regexp match endpts **/ *qualifiedpath, /** List of dirs which * are NOT already in path **/ **pathlist; /** List of dirs **/ const char *delim = _colon; /** path delimiter **/ int append = 1, /** append or prepend **/ numpaths, /** number of dirs in path **/ qpathlen, /** qualifiedpath length **/ arg1 = 1, /** arg start **/ x; /** loop index **/ Tcl_Obj *np_obj; /** new path Tcl Obj **/ #if WITH_DEBUGGING_CALLBACK ErrorLogger(NO_ERR_START, LOC, _proc_cmdSetPath, NULL); #endif /* WITH_DEBUGGING_CALLBACK */ /** ** Whatis mode? **/ if (g_flags & (M_WHATIS | M_HELP)) { goto success0; } /** ** Check arguments. There should be at least 3 args: ** argv[0] - prepend/append ** ... ** argv[n-1]- varname ** argv[n] - value **/ if(argc < 3) { if (OK != ErrorLogger(ERR_USAGE, LOC, argv[0], " path-variable directory", NULL)) { goto unwind0; } } /** ** Should this guy be removed from the variable(?)... If yes, then do so! **/ if (g_flags & M_REMOVE) { return (cmdRemovePath(client_data, interp, argc, argv)); /** ----> **/ } /** ** prepend or append. The default is append. **/ if (!(append = !!strncmp(argv[0], "pre", 3))) { sw_marker = PRE_SW_MARKER; } /** ** Non-persist mode? **/ if (g_flags & M_NONPERSIST) { return (TCL_OK); } /** ** Display only ... ok, let us do so! **/ if (g_flags & M_DISPLAY) { fprintf(stderr, "%s\t ", argv[0]); while (--argc) { fprintf( stderr, "%s ", *++argv); } fprintf(stderr, "\n"); goto success0; } /** ** Check for the delimiter option **/ if (*(argv[arg1]) == '-') { if (!strcmp(argv[arg1], "-d")) { delim = argv[(arg1 + 1)]; arg1 += 2; } else if (!strcmp(argv[arg1], "--delim")) { delim = argv[(arg1 + 1)]; arg1 += 2; } else if (!strncmp(argv[arg1], "--delim=", 8)) { delim = (argv[arg1] + 8); arg1++; } } /** ** Get the old value of the variable. MANPATH defaults to a configure ** generated value. ** Put a \ in front of each '.' and '+'. ** (this is an intentional memory leak) **/ oldpath = EMGetEnv(interp, argv[arg1]); _TCLCHK(interp) if(!oldpath || !*oldpath) { null_free((void *) &oldpath); oldpath = ((!strcmp(argv[arg1], "MANPATH")) ? stringer(NULL, 0, DEFAULTMANPATH, NULL) : stringer(NULL, 0, "", NULL)); } /** ** Split the new path into its components directories so each ** directory can be checked to see whether it is already in the ** existing path. **/ if (!(pathlist = SplitIntoList(interp, (char *)argv[(arg1 + 1)], &numpaths, delim))) { goto unwind0; } /** ** Some space for the list of paths which ** are not already in the existing path. **/ if((char *) NULL == (qualifiedpath = stringer(NULL, 0, argv[(arg1 + 1)], delim, NULL))) { if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) { goto unwind1; } } qpathlen = (int)(strlen(qualifiedpath) + 1); *qualifiedpath = '\0'; /** make sure null for later **/ for ((x = 0); (x < numpaths); x++) { regex_quote(pathlist[x], buffer, PATH_BUFLEN); /** ** Check to see if path is already in this path variable. ** It could be at the ** beginning ... ^path: ** middle ... :path: ** end ... :path$ ** only one ... ^path$ **/ if ((char *)NULL == (newpath = stringer(NULL, 0, "(^", buffer, delim, ")|(", delim, buffer, delim, ")|(", delim, buffer, "$)|(^", buffer, "$)", NULL))) { if (OK != ErrorLogger( ERR_STRING, LOC, NULL)) { goto unwind2; } } np_obj = Tcl_NewStringObj(newpath, (int)strlen(newpath)); chkexpPtr = Tcl_GetRegExpFromObj(interp, np_obj, TCL_REG_ADVANCED); _TCLCHK(interp) null_free((void *)&newpath); /** ** If the directory is not already in the path, ** add it to the qualified path. **/ if (!Tcl_RegExpExec(interp, chkexpPtr, oldpath, oldpath)) { if (!stringer((qualifiedpath + strlen(qualifiedpath)), (int)((unsigned long)qpathlen - strlen(qualifiedpath)), pathlist[x], delim, NULL)) { if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) { goto unwind2; } } } } /** End of loop that checks for ** already existent path **/ /** ** If all of the directories in the new path already exist, ** exit doing nothing. **/ if (! *qualifiedpath) { goto success1; } /* remove trailing delimiter */ qualifiedpath[(strlen(qualifiedpath) - 1)] = '\0'; /** ** Some space for our newly created path. ** We size at the oldpath plus the addition. **/ if (!(newpath = stringer(NULL, (int)(strlen(oldpath) + strlen(qualifiedpath) + 2), NULL))) { if (OK != ErrorLogger(ERR_STRING, LOC, NULL)) { goto unwind2; } } *newpath = '\0'; /** ** Easy job to do, if the old path has not been set up so far ... **/ if (!strcmp(oldpath, "")) { strcpy(newpath, qualifiedpath); /** ** Otherwise we have to take care on prepending vs. appending ... ** If there is a append or prepend marker within the variable (see ** modules_def.h) the changes are made according to this markers. Other- ** wise append and prepend will be relative to the strings begin or end. **/ } else { Tcl_Obj *sw_obj = Tcl_NewStringObj(sw_marker, (int)strlen(sw_marker)); Tcl_RegExp markexpPtr = Tcl_GetRegExpFromObj(interp, sw_obj, TCL_REG_ADVANCED); _TCLCHK(interp) strcpy(newpath, oldpath); if (Tcl_RegExpExec(interp, markexpPtr, oldpath, oldpath)) { _TCLCHK(interp) Tcl_RegExpRange(markexpPtr, 0, (CONST84 char **)&startp, (CONST84 char **)&endp); /** ** Append/Prepend marker found **/ if (append) { char ch = *startp; *startp = '\0'; strcpy(newpath, oldpath); /** ** check that newpath has a value before adding delim **/ if ((strlen(newpath) > 0) && (newpath[(strlen(newpath) - 1)] != *delim)) { strcat(newpath, delim); } strcat(newpath, qualifiedpath); if (newpath[strlen(newpath)-1] != *delim) { strcat(newpath, delim); } *startp = ch; strcat(newpath, startp); } else { char ch = *endp; *endp = '\0'; strcpy(newpath, oldpath); if (newpath[strlen(newpath)-1] != *delim) { strcat(newpath, delim); } strcat(newpath, qualifiedpath); *endp = ch; strcat(newpath, endp); } } else { /** ** No marker set **/ if (append) { strcpy(newpath, oldpath); if (newpath[strlen(newpath)-1] != *delim) { strcat(newpath, delim); } strcat(newpath, qualifiedpath); } else { strcpy(newpath, qualifiedpath); if (*oldpath != *delim) { strcat(newpath, delim); } strcat(newpath, oldpath); } /* end "if (append)" */ } /** end "if (marker)" **/ } /** end "if (strcmp)" **/ /** ** Now the new value to be set resides in 'newpath'. Set it up. **/ moduleSetenv(interp, (char *)argv[arg1], newpath, 1); _TCLCHK(interp) #if WITH_DEBUGGING_CALLBACK ErrorLogger(NO_ERR_END, LOC, _proc_cmdSetPath, NULL); #endif /* WITH_DEBUGGING_CALLBACK */ /** ** Free resources **/ null_free((void *)&newpath); success1: null_free((void *)&oldpath); null_free((void *)&qualifiedpath); FreeList(pathlist, numpaths); success0: return (TCL_OK); /** -------- EXIT (SUCCESS) -------> **/ unwind2: null_free((void *)&qualifiedpath); unwind1: FreeList(pathlist, numpaths); unwind0: null_free((void *)&oldpath); return (TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/ } /** End of 'cmdSetPath' **/