static STLW::string GetBaseDir(const STLW::string & szTemplateName, STLW::string & sNormalizedFileName) { if (szTemplateName.length() == 0) { return ""; } STLW::vector<STLW::string> vCurrentDir; CCHAR_P sBegin = szTemplateName.c_str(); CCHAR_P szEnd = szTemplateName.c_str() + szTemplateName.length(); CCHAR_P sIter = sBegin; while (sIter != szEnd) { if (*sIter == '/') { if (sIter != sBegin) { STLW::string sTMP(sBegin, sIter); if (sTMP == "/." || sTMP == "/") { ;; } else if (sTMP == "/..") { STLW::vector<STLW::string>::iterator itEnd = vCurrentDir.end(); if (vCurrentDir.begin() == itEnd) { return ""; } vCurrentDir.erase(--itEnd); } else { vCurrentDir.push_back(sTMP); } } sBegin = sIter; } ++sIter; } STLW::string sTMP(sBegin, sIter); if (sTMP == "/") { return ""; } STLW::string sResult; for (UINT_32 iI = 0; iI < vCurrentDir.size(); ++iI) { sResult.append(vCurrentDir[iI]); } sNormalizedFileName.assign(sResult); sNormalizedFileName.append(sTMP); sResult.append("/"); return sResult; }
// // Load template with specified name // INT_32 CTPP2FileSourceLoader::LoadTemplate(CCHAR_P szTemplateName) { sNormalizedFileName.erase(); INT_32 iStatCode = 0; STLW::vector<STLW::string>::const_iterator itvIncludeDirs = vIncludeDirs.begin(); while(itvIncludeDirs != vIncludeDirs.end()) { STLW::string sTMP = *itvIncludeDirs; #ifdef WIN32 if ( sTMP.length() && sTMP[sTMP.length() - 1] != '/' && sTMP[sTMP.length() - 1] != '\\' ) { sTMP.append("\\", 1); } #else if (sTMP.length() && sTMP[sTMP.length() - 1] != '/') { sTMP.append("/", 1); } #endif sTMP.append(szTemplateName); sCurrentDir = GetBaseDir(sTMP, sNormalizedFileName); if (sNormalizedFileName.length() == 0) { STLW::string sError("invalid file name `"); sError.append(sTMP); sError.append("`"); throw CTPPLogicError(sError.c_str()); } // Get file size struct stat oStat; iStatCode = stat(sNormalizedFileName.c_str(), &oStat); if (iStatCode == 0) { iTemplateSize = oStat.st_size; break; } ++itvIncludeDirs; } if (iStatCode == -1) { STLW::string sError("cannot find file in include directories "); itvIncludeDirs = vIncludeDirs.begin(); for (;;) { sError.append("`"); if (itvIncludeDirs -> size() != 0) { sError.append(*itvIncludeDirs); } else { CHAR_P szPWD = getcwd(NULL, 0); sError.append(szPWD); free(szPWD); } sError.append("`"); ++itvIncludeDirs; if (itvIncludeDirs == vIncludeDirs.end()) { break; } sError.append(", "); } throw CTPPLogicError(sError.c_str()); } if (iTemplateSize == 0) { STLW::string sError("empty file `"); sError.append(sNormalizedFileName); sError.append("` found"); throw CTPPLogicError(sError.c_str()); } // Load file FILE * F = fopen(sNormalizedFileName.c_str(), "rb"); if (F == NULL) { throw CTPPUnixException("fopen", errno); } if (sTemplate != NULL) { free(sTemplate); } // Allocate memory sTemplate = (CHAR_P)malloc(iTemplateSize); // Read from file if (fread(sTemplate, iTemplateSize, 1, F) != 1) { if (ferror(F) != 0) { free(sTemplate); fclose(F); throw CTPPUnixException("fread", errno); } else { free(sTemplate); fclose(F); throw CTPPLogicError("Cannot read from file"); } } fclose(F); return 0; }
void CTPP2::output(zval *out, Bytecode *bytecode, const char *src_enc, const char *dst_enc) { unsigned int IP = 0; if (!bytecode || !bytecode->check()) { error = CTPPError("", "Invalid Bytecode", CTPP_VM_ERROR | STL_UNKNOWN_ERROR, 0, 0, IP); } else { try { if (charset.convert || (src_enc && dst_enc)) { STLW::string src_charset, dst_charset; if (src_enc && dst_enc) { src_charset = STLW::string(src_enc); dst_charset = STLW::string(dst_enc); } else { src_charset = charset.src; dst_charset = charset.dst; } STLW::string result; CTPPPerlLogger logger; StringIconvOutputCollector output_collector(result, src_charset, dst_charset, 3); vm->Init(bytecode->getCode(), &output_collector, &logger); vm->Run(bytecode->getCode(), &output_collector, IP, *params, &logger); vm->Reset(); ZVAL_STRINGL(out, result.data(), result.length()); return; } else { CTPPPerlLogger logger; if (out) { // STLW::string result; // StringOutputCollector output_collector(result); // vm->Init(bytecode->getCode(), &output_collector, &logger); // vm->Run(bytecode->getCode(), &output_collector, IP, *params, &logger); // ZVAL_STRINGL(out, result.data(), result.length()); CTPPPHPVarOutputCollector output_collector(out); vm->Init(bytecode->mem, &output_collector, &logger); vm->Run(bytecode->mem, &output_collector, IP, *params, &logger); } else { CTPPPHPOutputCollector output_collector; vm->Init(bytecode->mem, &output_collector, &logger); vm->Run(bytecode->mem, &output_collector, IP, *params, &logger); } vm->Reset(); return; } } catch (ZeroDivision &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_ZERO_DIVISION_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (ExecutionLimitReached &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_EXECUTION_LIMIT_REACHED_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (CodeSegmentOverrun &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_CODE_SEGMENT_OVERRUN_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (InvalidSyscall &e) { if (e.GetIP() != 0) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_INVALID_SYSCALL_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } else { error = CTPPError(e.GetSourceName(), STLW::string("Unsupported syscall: \"") + e.what() + "\"", CTPP_VM_ERROR | CTPP_INVALID_SYSCALL_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } } catch (IllegalOpcode &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_ILLEGAL_OPCODE_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (StackOverflow &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_STACK_OVERFLOW_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (StackUnderflow &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_STACK_UNDERFLOW_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (VMException &e) { error = CTPPError(e.GetSourceName(), e.what(), CTPP_VM_ERROR | CTPP_VM_GENERIC_ERROR, VMDebugInfo(e.GetDebugInfo()).GetLine(), VMDebugInfo(e.GetDebugInfo()).GetLinePos(), e.GetIP()); } catch (CTPPUnixException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_UNIX_ERROR, 0, 0, IP); } catch (CDTRangeException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_RANGE_ERROR, 0, 0, IP); } catch (CDTAccessException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_ACCESS_ERROR, 0, 0, IP); } catch (CDTTypeCastException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_TYPE_CAST_ERROR, 0, 0, IP); } catch (CTPPLogicError &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_LOGIC_ERROR, 0, 0, IP); } catch(CTPPCharsetRecodeException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_CHARSET_RECODE_ERROR, 0, 0, 0); } catch (CTPPException &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | CTPP_UNKNOWN_ERROR, 0, 0, IP); } catch (STLW::exception &e) { error = CTPPError("", e.what(), CTPP_VM_ERROR | STL_UNKNOWN_ERROR, 0, 0, IP); } catch (...) { error = CTPPError("", "Unknown Error", CTPP_VM_ERROR | STL_UNKNOWN_ERROR, 0, 0, IP); } } vm->Reset(); if (error.line > 0) { php_error(E_WARNING, "CTPP2::output(): %s (error code 0x%08X); IP: 0x%08X, file %s line %d pos %d", error.error_descr.c_str(), error.error_code, error.ip, error.template_name.c_str(), error.line, error.pos); } else { php_error(E_WARNING, "CTPP2::output(): %s (error code 0x%08X); IP: 0x%08X", error.error_descr.c_str(), error.error_code, error.ip); } if (out) ZVAL_BOOL(out, 0); }