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;
}
Beispiel #3
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);
}