<commit_before>#include "consolemodel.h"
#include "globals.h"

enum {
    ModelDataRole = Qt::UserRole + 1
};

ConsoleModel::ConsoleModel(QObject *parent) :
    QAbstractListModel(parent)
{
}

ConsoleModel::~ConsoleModel()
{
}

int ConsoleModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_lines.count();
}

QVariant ConsoleModel::data(const QModelIndex &index, int role) const
{
    Q_UNUSED(role);
    if (!index.isValid() || index.row() > m_lines.count()-1)
        return QVariant();

    QString line = m_lines.at(index.row());
    return line;
}

QHash<int, QByteArray> ConsoleModel::roleNames() const
{
    QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
    roles.insert(ModelDataRole, QByteArray("modelData"));
    return roles;
}

void ConsoleModel::setLines(QStringList lines)
{
    if (m_lines == lines)
        return;

    beginResetModel();
    m_lines = lines;
    endResetModel();

    emit linesChanged();
}

void ConsoleModel::setLines(QString lines)
{
    beginResetModel();
    m_lines = lines.split(QRegExp("[\n\r]"));
    endResetModel();
    emit linesChanged();
}

void ConsoleModel::appendLine(QString line)
{
    beginInsertRows(QModelIndex(), m_lines.count(), m_lines.count());
    m_lines.append(line);
    endInsertRows();
}

void ConsoleModel::executeCommand(QString command, QStringList arguments)
{
    setLines(QStringList());

    // process is killed when Page is closed - should run this in bg thread to allow command finish(?)
    m_process = new QProcess(this);
    m_process->setReadChannel(QProcess::StandardOutput);
    m_process->setProcessChannelMode(QProcess::MergedChannels); // merged stderr channel with stdout channel
    connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readProcessChannels()));
    connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleProcessFinish(int, QProcess::ExitStatus)));
    connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleProcessError(QProcess::ProcessError)));
    m_process->start(command, arguments);
}

void ConsoleModel::readProcessChannels()
{
    while (m_process->canReadLine()) {
        QString line = m_process->readLine();
        appendLine(line);
    }
}

void ConsoleModel::handleProcessFinish(int exitCode, QProcess::ExitStatus status)
{
    if (status == QProcess::CrashExit) { // if it crashed, then use some error exit code
        exitCode = -99999;
        appendLine(tr("** crashed"));

    } else if (exitCode != 0) {
        appendLine(tr("** error: %1").arg(exitCode));
    }
    emit processExited(exitCode);
}

void ConsoleModel::handleProcessError(QProcess::ProcessError error)
{
    Q_UNUSED(error);
    emit processExited(-88888); // if error, then use some error exit code
    appendLine(tr("** error"));
}
<commit_msg>A process will now wait until the previous process is done before starting<commit_after>#include "consolemodel.h"
#include "globals.h"

enum {
    ModelDataRole = Qt::UserRole + 1
};

ConsoleModel::ConsoleModel(QObject *parent) :
    QAbstractListModel(parent)
{
    m_process = new QProcess(this);
}

ConsoleModel::~ConsoleModel()
{
}

int ConsoleModel::rowCount(const QModelIndex &parent) const
{
    Q_UNUSED(parent);
    return m_lines.count();
}

QVariant ConsoleModel::data(const QModelIndex &index, int role) const
{
    Q_UNUSED(role);
    if (!index.isValid() || index.row() > m_lines.count()-1)
        return QVariant();

    QString line = m_lines.at(index.row());
    return line;
}

QHash<int, QByteArray> ConsoleModel::roleNames() const
{
    QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
    roles.insert(ModelDataRole, QByteArray("modelData"));
    return roles;
}

void ConsoleModel::setLines(QStringList lines)
{
    if (m_lines == lines)
        return;

    beginResetModel();
    m_lines = lines;
    endResetModel();

    emit linesChanged();
}

void ConsoleModel::setLines(QString lines)
{
    beginResetModel();
    m_lines = lines.split(QRegExp("[\n\r]"));
    endResetModel();
    emit linesChanged();
}

void ConsoleModel::appendLine(QString line)
{
    beginInsertRows(QModelIndex(), m_lines.count(), m_lines.count());
    m_lines.append(line);
    endInsertRows();
}

void ConsoleModel::executeCommand(QString command, QStringList arguments)
{
    // process is killed when Page is closed - should run this in bg thread to allow command finish(?)
    if(m_process->state()!=QProcess::NotRunning) //the process is still busy
        if(!m_process->waitForFinished(500)) //wait for it to finish
            return;
    setLines(QStringList());
    m_process = new QProcess(this);
    m_process->setReadChannel(QProcess::StandardOutput);
    m_process->setProcessChannelMode(QProcess::MergedChannels); // merged stderr channel with stdout channel
    connect(m_process, SIGNAL(readyReadStandardOutput()), this, SLOT(readProcessChannels()));
    connect(m_process, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleProcessFinish(int, QProcess::ExitStatus)));
    connect(m_process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(handleProcessError(QProcess::ProcessError)));
    m_process->start(command, arguments);
}

void ConsoleModel::readProcessChannels()
{
    while (m_process->canReadLine()) {
        QString line = m_process->readLine();
        appendLine(line);
    }
}

void ConsoleModel::handleProcessFinish(int exitCode, QProcess::ExitStatus status)
{
    if (status == QProcess::CrashExit) { // if it crashed, then use some error exit code
        exitCode = -99999;
        appendLine(tr("** crashed"));

    } else if (exitCode != 0) {
        appendLine(tr("** error: %1").arg(exitCode));
    }
    emit processExited(exitCode);
}

void ConsoleModel::handleProcessError(QProcess::ProcessError error)
{
    Q_UNUSED(error);
    emit processExited(-88888); // if error, then use some error exit code
    appendLine(tr("** error"));
}
<|endoftext|>


<commit_before>{
   //
   // To see the output of this macro, click begin_html here end_html
   //
   gROOT->Reset();
   c1 = new TCanvas("c1","Surfaces Drawing Options",200,10,700,900);
   c1->SetFillColor(42);
   gStyle->SetFrameFillColor(42);
   title = new TPaveText(.2,0.96,.8,.995);
   title->SetFillColor(33);
   title->AddText("Examples of Surface options");
   title->Draw();

   pad1 = new TPad("pad1","Gouraud shading",0.03,0.50,0.98,0.95,21);
   pad2 = new TPad("pad2","Color mesh",0.03,0.02,0.98,0.48,21);
   pad1->Draw();
   pad2->Draw();
   //
   // We generate a 2-D function
   TF2 *f2 = new TF2("f2","x**2 + y**2 - x**3 -8*x*y**4",-1,1.2,-1.5,1.5);
   f2->SetContour(48);
   f2->SetFillColor(45);

   // Draw this function in pad1 with Gouraud shading option
   pad1->cd();
   pad1->SetPhi(-80);
   pad1->SetLogz();
   f2->Draw("surf4");

   // Draw this function in pad2 with color mesh option
   pad2->cd();
   pad2->SetTheta(25);
   pad2->SetPhi(-110);
   pad2->SetLogz();
   f2->Draw("surf1");

}
<commit_msg>Extend tutorial surfaces.C to show how to set the axis titles in case of functions drawn in several pads.<commit_after>{
   //
   // To see the output of this macro, click begin_html here end_html
   //
   gROOT->Reset();
   c1 = new TCanvas("c1","Surfaces Drawing Options",200,10,700,900);
   c1->SetFillColor(42);
   gStyle->SetFrameFillColor(42);
   title = new TPaveText(.2,0.96,.8,.995);
   title->SetFillColor(33);
   title->AddText("Examples of Surface options");
   title->Draw();

   pad1 = new TPad("pad1","Gouraud shading",0.03,0.50,0.98,0.95,21);
   pad2 = new TPad("pad2","Color mesh",0.03,0.02,0.98,0.48,21);
   pad1->Draw();
   pad2->Draw();
   //
   // We generate a 2-D function
   TF2 *f2 = new TF2("f2","x**2 + y**2 - x**3 -8*x*y**4",-1,1.2,-1.5,1.5);
   f2->SetContour(48);
   f2->SetFillColor(45);

   // Draw this function in pad1 with Gouraud shading option
   pad1->cd();
   pad1->SetPhi(-80);
   pad1->SetLogz();
   f2->Draw("surf4");

   // Draw this function in pad2 with color mesh option
   pad2->cd();
   pad2->SetTheta(25);
   pad2->SetPhi(-110);
   pad2->SetLogz();
   f2->Draw("surf1");

   //add axis titles. The titles are set on the intermediate
   //histogram used for visualisation. We must force this histogram
   //to be created, then force the redrawing of the two pads
   pad2->Update();
   f2->GetHistogram()->GetXaxis()->SetTitle("x title");
   f2->GetHistogram()->GetYaxis()->SetTitle("y title");
   f2->GetHistogram()->GetXaxis()->SetTitleOffset(1.4);
   f2->GetHistogram()->GetYaxis()->SetTitleOffset(1.4);
   pad1->Modified();
   pad2->Modified();
}
<|endoftext|>


<commit_before>#ifndef STATIC_NEW_HPP
# define STATIC_NEW_HPP
# pragma once

#include <new>
#include <type_traits>

namespace gnr
{

template <typename A, std::size_t N = 128>
class static_new
{
  std::conditional_t<
    std::is_array_v<A>,
    std::decay_t<A>,
    A*
  > p_;

  static constinit inline std::size_t c_; // instance counter

  template <auto>
  static constinit inline std::aligned_storage_t<
    sizeof(A),
    alignof(A)
  > storage_;

  static constinit struct deleter
  {
    ~deleter()
      noexcept(std::is_nothrow_destructible_v<A>)
    {
      [&]<auto ...I>(auto const c, std::index_sequence<I...>)
      {
        (
          (
            I < c ?
              std::launder(reinterpret_cast<A*>(&storage_<I>))->~A() :
              void()
          ),
          ...
        );
      }(c_, std::make_index_sequence<N>());
    }
  } const d_;

public:
  explicit static_new(auto&& ...a)
    noexcept(std::is_nothrow_constructible_v<A, decltype(a)...>)
  {
    [&]<auto ...I>(auto const c, std::index_sequence<I...>)
    {
      (
        (
          I == c ?
            p_ = ::new (&storage_<I>) A(std::forward<decltype(a)>(a)...) :
            nullptr
        ),
        ...
      );
    }(c_++, std::make_index_sequence<N>());
  }

  static_new(static_new const&) = delete;
  static_new(static_new&&) = delete;

  //
  static_new& operator=(static_new const&) = delete;
  static_new& operator=(static_new&&) = delete;

  //
  operator decltype(p_)() noexcept { return p_; }
};

}

#endif // STATIC_NEW_HPP
<commit_msg>some fixes<commit_after>#ifndef STATIC_NEW_HPP
# define STATIC_NEW_HPP
# pragma once

#include <new>
#include <type_traits>

namespace gnr
{

template <typename A, std::size_t N = 128>
class static_new
{
  std::conditional_t<
    std::is_array_v<A>,
    std::decay_t<A>,
    A*
  > p_;

  static constinit inline std::size_t c_; // instance counter

  template <auto>
  static constinit inline std::aligned_storage_t<
    sizeof(A),
    alignof(A)
  > storage_;

  static constinit inline struct deleter
  {
    ~deleter()
      noexcept(std::is_nothrow_destructible_v<A>)
    {
      [&]<auto ...I>(auto const c, std::index_sequence<I...>)
      {
        (
          (
            I < c ?
              std::launder(reinterpret_cast<A*>(&storage_<I>))->~A() :
              void()
          ),
          ...
        );
      }(c_, std::make_index_sequence<N>());
    }
  } const d_;

public:
  explicit static_new(auto&& ...a)
    noexcept(std::is_nothrow_constructible_v<A, decltype(a)...>)
  {
    [&]<auto ...I>(auto const c, std::index_sequence<I...>)
    {
      (
        (
          I == c ?
            p_ = ::new (&storage_<I>) A(std::forward<decltype(a)>(a)...) :
            nullptr
        ),
        ...
      );
    }(c_++, std::make_index_sequence<N>());
  }

  static_new(static_new const&) = delete;
  static_new(static_new&&) = delete;

  //
  static_new& operator=(static_new const&) = delete;
  static_new& operator=(static_new&&) = delete;

  //
  operator decltype(p_)() noexcept { return p_; }
};

}

#endif // STATIC_NEW_HPP
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

/* ************************************************************************** */
/* User Pool                                            	 	      */
/* ************************************************************************** */

#include "UserPool.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"

#include <fstream>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::init_cb(void *nil, int num, char **values, char **names)
{
    if ( num == 0 || values == 0 || values[0] == 0 )
    {
        return -1;
    }

    known_users.insert(make_pair(values[1],atoi(values[0])));

    return 0;
}

/* -------------------------------------------------------------------------- */

UserPool::UserPool(SqlDB * db):PoolSQL(db,User::table)
{
    ostringstream   sql;

    set_callback(static_cast<Callbackable::Callback>(&UserPool::init_cb));

    sql  << "SELECT oid,user_name FROM " <<  User::table;

    db->exec(sql, this);

    unset_callback();

    if ((int) known_users.size() == 0)
    {
        // User oneadmin needs to be added in the bootstrap
        int           one_uid = -1;
        ostringstream oss;
        string        one_token;
        string        one_name;
        string        one_pass;
        string        one_auth_file;

        const char *  one_auth;
        ifstream      file;

        one_auth = getenv("ONE_AUTH");

        if (!one_auth)
        {
            struct passwd * pw_ent;

            pw_ent = getpwuid(getuid());

            if ((pw_ent != NULL) && (pw_ent->pw_dir != NULL))
            {
                one_auth_file = pw_ent->pw_dir;
                one_auth_file += "/.one/one_auth";

                one_auth = one_auth_file.c_str();
            }
            else
            {
                oss << "Could not get one_auth file location";
            }
        }

        file.open(one_auth);

        if (file.good())
        {
            getline(file,one_token);

            if (file.fail())
            {
                oss << "Error reading file: " << one_auth;
            }
            else
            {
                if (User::split_secret(one_token,one_name,one_pass) == 0)
                {
                    string sha1_pass = User::sha1_digest(one_pass);
                    allocate(&one_uid, one_name, sha1_pass, true);
                }
                else
                {
                    oss << "Wrong format must be <username>:<password>";
                }
            }
        }
        else
        {
            oss << "Cloud not open file: " << one_auth;
        }

        file.close();

        if (one_uid != 0)
        {
            NebulaLog::log("ONE",Log::ERROR,oss);
            throw;
        }
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::allocate (
    int *  oid,
    string username,
    string password,
    bool   enabled)
{
    User *        user;

    // Build a new User object

    user = new User(-1,
        username,
        password,
        enabled);

    // Insert the Object in the pool

    *oid = PoolSQL::allocate(user);

    if (*oid != -1)
    {
        // Add the user to the map of known_users
        known_users.insert(make_pair(username,*oid));
    }

    return *oid;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::authenticate(string& session)
{
    map<string, int>::iterator index;

    User * user = 0;
    string username;
    string secret, u_pass;
    int    uid;

    int user_id = -1;
    int rc;

    Nebula&     nd      = Nebula::instance();
    AuthManager * authm = nd.get_authm();

    rc = User::split_secret(session,username,secret);

    if ( rc != 0 )
    {
        return -1;
    }

    index = known_users.find(username);

    if ( index != known_users.end() ) //User known to OpenNebula
    {
        user = get((int)index->second,true);

        if ( user == 0 )
        {
            return -1;
        }

        u_pass = user->password;
        uid    = user->get_uid();

        user->unlock();
    }
    else //External User
    {
        u_pass = "-";
        uid    = -1;
    }

    AuthRequest ar(uid);

    ar.add_authenticate(username,u_pass,secret);

    if ( uid == 0 ) //oneadmin
    {
        if (ar.plain_authenticate())
        {
            user_id = 0;
        }
    }
    else if (authm == 0) //plain auth
    {
        if ( user != 0 && ar.plain_authenticate()) //no plain for external users
        {
            user_id = uid;
        }
    }
    else //use the driver
    {
        authm->trigger(AuthManager::AUTHENTICATE,&ar);
        ar.wait();

        if (ar.result==true)
        {
            if ( user != 0 ) //knwon user_id
            {
                user_id = uid;
            }
            else //External user, user_id in driver message
            {
                istringstream is(ar.message);

                if ( is.good() )
                {
                    is >> user_id;
                }

                if ( is.fail() || user_id <= 0 )
                {
                    ar.message = "Can't convert user_id from driver";
                    user_id    = -1;
                }
            }
        }

        if (user_id == -1)
        {
            ostringstream oss;
            oss << "Auth Error: " << ar.message;

            NebulaLog::log("AuM",Log::ERROR,oss);
        }
    }

    return user_id;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::authorize(AuthRequest& ar)
{
    Nebula&       nd    = Nebula::instance();
    AuthManager * authm = nd.get_authm();
    int           rc    = -1;

    if (authm == 0)
    {
        if (ar.plain_authorize())
        {
            rc = 0;
        }
    }
    else
    {
        authm->trigger(AuthManager::AUTHORIZE,&ar);
        ar.wait();

        if (ar.result==true)
        {
            rc = 0;
        }
        else
        {
            ostringstream oss;
            oss << "Auth Error: " << ar.message;

            NebulaLog::log("AuM",Log::ERROR,oss);
        }
    }

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::dump_cb(void * _oss, int num, char **values, char **names)
{
    ostringstream * oss;

    oss = static_cast<ostringstream *>(_oss);

    return User::dump(*oss, num, values, names);
}

/* -------------------------------------------------------------------------- */

int UserPool::dump(ostringstream& oss, const string& where)
{
    int             rc;
    ostringstream   cmd;

    oss << "<USER_POOL>";

    set_callback(static_cast<Callbackable::Callback>(&UserPool::dump_cb),
                 static_cast<void *>(&oss));

    cmd << "SELECT * FROM " << User::table;

    if ( !where.empty() )
    {
        cmd << " WHERE " << where;
    }

    rc = db->exec(cmd, this);

    unset_callback();

    oss << "</USER_POOL>";

    return rc;
}
<commit_msg>bug : Not known users are automatically added if authorized by the driver (cherry picked from commit 859148e8671012d510f8195102a4c87ef2f4dfe4)<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2010, OpenNebula Project Leads (OpenNebula.org)             */
/*                                                                            */
/* Licensed under the Apache License, Version 2.0 (the "License"); you may    */
/* not use this file except in compliance with the License. You may obtain    */
/* a copy of the License at                                                   */
/*                                                                            */
/* http://www.apache.org/licenses/LICENSE-2.0                                 */
/*                                                                            */
/* Unless required by applicable law or agreed to in writing, software        */
/* distributed under the License is distributed on an "AS IS" BASIS,          */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   */
/* See the License for the specific language governing permissions and        */
/* limitations under the License.                                             */
/* -------------------------------------------------------------------------- */

/* ************************************************************************** */
/* User Pool                                            	 	      */
/* ************************************************************************** */

#include "UserPool.h"
#include "NebulaLog.h"
#include "Nebula.h"
#include "AuthManager.h"

#include <fstream>
#include <sys/types.h>
#include <pwd.h>
#include <stdlib.h>

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::init_cb(void *nil, int num, char **values, char **names)
{
    if ( num == 0 || values == 0 || values[0] == 0 )
    {
        return -1;
    }

    known_users.insert(make_pair(values[1],atoi(values[0])));

    return 0;
}

/* -------------------------------------------------------------------------- */

UserPool::UserPool(SqlDB * db):PoolSQL(db,User::table)
{
    ostringstream   sql;

    set_callback(static_cast<Callbackable::Callback>(&UserPool::init_cb));

    sql  << "SELECT oid,user_name FROM " <<  User::table;

    db->exec(sql, this);

    unset_callback();

    if ((int) known_users.size() == 0)
    {
        // User oneadmin needs to be added in the bootstrap
        int           one_uid = -1;
        ostringstream oss;
        string        one_token;
        string        one_name;
        string        one_pass;
        string        one_auth_file;

        const char *  one_auth;
        ifstream      file;

        one_auth = getenv("ONE_AUTH");

        if (!one_auth)
        {
            struct passwd * pw_ent;

            pw_ent = getpwuid(getuid());

            if ((pw_ent != NULL) && (pw_ent->pw_dir != NULL))
            {
                one_auth_file = pw_ent->pw_dir;
                one_auth_file += "/.one/one_auth";

                one_auth = one_auth_file.c_str();
            }
            else
            {
                oss << "Could not get one_auth file location";
            }
        }

        file.open(one_auth);

        if (file.good())
        {
            getline(file,one_token);

            if (file.fail())
            {
                oss << "Error reading file: " << one_auth;
            }
            else
            {
                if (User::split_secret(one_token,one_name,one_pass) == 0)
                {
                    string sha1_pass = User::sha1_digest(one_pass);
                    allocate(&one_uid, one_name, sha1_pass, true);
                }
                else
                {
                    oss << "Wrong format must be <username>:<password>";
                }
            }
        }
        else
        {
            oss << "Cloud not open file: " << one_auth;
        }

        file.close();

        if (one_uid != 0)
        {
            NebulaLog::log("ONE",Log::ERROR,oss);
            throw;
        }
    }
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::allocate (
    int *  oid,
    string username,
    string password,
    bool   enabled)
{
    User *        user;

    // Build a new User object

    user = new User(-1,
        username,
        password,
        enabled);

    // Insert the Object in the pool

    *oid = PoolSQL::allocate(user);

    if (*oid != -1)
    {
        // Add the user to the map of known_users
        known_users.insert(make_pair(username,*oid));
    }

    return *oid;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::authenticate(string& session)
{
    map<string, int>::iterator index;

    User * user = 0;
    string username;
    string secret, u_pass;
    int    uid;

    int user_id = -1;
    int rc;

    Nebula&     nd      = Nebula::instance();
    AuthManager * authm = nd.get_authm();

    rc = User::split_secret(session,username,secret);

    if ( rc != 0 )
    {
        return -1;
    }

    index = known_users.find(username);

    if ( index != known_users.end() ) //User known to OpenNebula
    {
        user = get((int)index->second,true);

        if ( user == 0 )
        {
            return -1;
        }

        u_pass = user->password;
        uid    = user->get_uid();

        user->unlock();
    }
    else //External User
    {
        u_pass = "-";
        uid    = -1;
    }

    AuthRequest ar(uid);

    ar.add_authenticate(username,u_pass,secret);

    if ( uid == 0 ) //oneadmin
    {
        if (ar.plain_authenticate())
        {
            user_id = 0;
        }
    }
    else if (authm == 0) //plain auth
    {
        if ( user != 0 && ar.plain_authenticate()) //no plain for external users
        {
            user_id = uid;
        }
    }
    else //use the driver
    {
        authm->trigger(AuthManager::AUTHENTICATE,&ar);
        ar.wait();

        if (ar.result==true)
        {
            if ( user != 0 ) //knwon user_id
            {
                user_id = uid;
            }
            else //External user, username & pass in driver message
            {
                string mad_name;
                string mad_pass;

                istringstream is(ar.message);

                if ( is.good() )
                {
                    is >> mad_name >> ws >> mad_pass;
                }

                if ( !is.fail() )
                {
                    allocate(&user_id,mad_name,mad_pass,true);
                }

                if ( user_id == -1 )
                {
                    ostringstream oss;

                    oss << "Can't create user from driver response: "
                        << ar.message;

                    ar.message = oss.str();
                    user_id    = -1;
                }
            }
        }

        if (user_id == -1)
        {
            ostringstream oss;
            oss << "Auth Error: " << ar.message;

            NebulaLog::log("AuM",Log::ERROR,oss);
        }
    }

    return user_id;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::authorize(AuthRequest& ar)
{
    Nebula&       nd    = Nebula::instance();
    AuthManager * authm = nd.get_authm();
    int           rc    = -1;

    if (authm == 0)
    {
        if (ar.plain_authorize())
        {
            rc = 0;
        }
    }
    else
    {
        authm->trigger(AuthManager::AUTHORIZE,&ar);
        ar.wait();

        if (ar.result==true)
        {
            rc = 0;
        }
        else
        {
            ostringstream oss;
            oss << "Auth Error: " << ar.message;

            NebulaLog::log("AuM",Log::ERROR,oss);
        }
    }

    return rc;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */

int UserPool::dump_cb(void * _oss, int num, char **values, char **names)
{
    ostringstream * oss;

    oss = static_cast<ostringstream *>(_oss);

    return User::dump(*oss, num, values, names);
}

/* -------------------------------------------------------------------------- */

int UserPool::dump(ostringstream& oss, const string& where)
{
    int             rc;
    ostringstream   cmd;

    oss << "<USER_POOL>";

    set_callback(static_cast<Callbackable::Callback>(&UserPool::dump_cb),
                 static_cast<void *>(&oss));

    cmd << "SELECT * FROM " << User::table;

    if ( !where.empty() )
    {
        cmd << " WHERE " << where;
    }

    rc = db->exec(cmd, this);

    unset_callback();

    oss << "</USER_POOL>";

    return rc;
}
<|endoftext|>


<commit_before>#define SPICA_IMAGE_EXPORT
#include "image.h"

#if defined(_WIN32) || defined(__WIN32__)
#define PACKED(__declare__) __pragma(pack(push,1)) __declare__ __pragma(pack(pop))
#else
#define PACKED(__declare__) __declare__ __attribute__((__packed__))
#endif

#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <algorithm>

#include "common.h"

namespace spica {

    namespace {
        PACKED(
        struct BitmapFileHeader {
            unsigned short bfType;
            unsigned long  bfSize;
            unsigned short bfReserved1;
            unsigned short bfReserved2;
            unsigned long  bfOffBits;
        });

        PACKED(
        struct BitmapCoreHeader {
            unsigned long biSize;
            long biWidth;
            long biHeight;
            unsigned short biPlanes;
            unsigned short biBitCount;
            unsigned long biCompression;
            unsigned long biSizeImage;
            long biXPixPerMeter;
            long biYPixPerMeter;
            unsigned long biClrUsed;
            unsigned long biClrImportant;
        });

        PACKED(
        struct RGBTriple {
            unsigned char rgbBlue;
            unsigned char rgbGreen;
            unsigned char rgbRed;
        });
    }

    Image::Image()
        : _width(0)
        , _height(0)
        , _pixels(0)
    {
    }

    Image::Image(int width, int height)
        : _width(width)
        , _height(height)
        , _pixels(0)
    {
        msg_assert(width >= 0 && height >= 0, "Image size must be positive");
        _pixels = new Color[_width * _height];
    }

    Image::Image(const Image& image)
        : _width(image._width)
        , _height(image._height)
        , _pixels(new Color[image._width * image._height])
    {
        memcpy(_pixels, image._pixels, sizeof(Color) * image._width * image._height);
    }

    Image::~Image()
    {
        delete[] _pixels;
    }

    Image& Image::operator=(const Image& image) {
        delete[] _pixels;

        this->_width = image._width;
        this->_height = image._height;
        this->_pixels = new Color[image._width * image._height];
        memcpy(_pixels, image._pixels, sizeof(Color) * image._width * image._height);

        return *this;
    }

    const Color& Image::operator()(int x, int y) const {
        msg_assert(0 <= x && x < _width && 0 <= y && y < _height, "Pixel index out of bounds");
        return _pixels[y * _width + x];
    }

    Color& Image::pixel(int x, int y) {
        msg_assert(0 <= x && x < _width && 0 <= y && y < _height, "Pixel index out of bounds");
        return _pixels[y * _width + x];
    }

    void Image::loadBMP(const std::string& filename) {
        BitmapFileHeader header;
        BitmapCoreHeader core;

        printf("ho");
        std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
        printf("ge\n");
        msg_assert(ifs.is_open(), "Failed to open file!!");

        ifs.read((char*)&header, sizeof(BitmapFileHeader));
        ifs.read((char*)&core, sizeof(BitmapCoreHeader));
        printf("header: %ld\n", sizeof(BitmapFileHeader));
        printf("  core: %ld\n", sizeof(BitmapCoreHeader));

        this->_width  = std::abs(core.biWidth);
        this->_height = std::abs(core.biHeight);
        this->_pixels = new Color[_width * _height];

        const int lineSize = (sizeof(RGBTriple) * _width + 3) / 4 * 4;
        char* lineBits = new char[lineSize];
        for (int y = 0; y < _height; y++) {
            ifs.read((char*)lineBits, lineSize);
            char* ptr = lineBits;
            for (int x = 0; x < _width; x++) {
                RGBTriple triple;
                memcpy(&triple, ptr, sizeof(RGBTriple));

                double red   = toReal(triple.rgbRed);
                double green = toReal(triple.rgbGreen);
                double blue  = toReal(triple.rgbBlue);
                this->_pixels[y * _width + x] = Color(red, green, blue);
                ptr += sizeof(RGBTriple);
            }
        }
        delete[] lineBits;

        ifs.close();
    }

    void Image::saveBMP(const std::string& filename) const {
        const int lineSize = (sizeof(RGBTriple) * _width + 3) / 4 * 4;
        const int totalSize = lineSize * _height;
        const int offBits = sizeof(BitmapFileHeader) + sizeof(BitmapCoreHeader);

        // Prepare file header
        BitmapFileHeader header;
        header.bfType = 'B' | ('M' << 8);
        header.bfSize = offBits + totalSize;
        header.bfReserved1 = 0;
        header.bfReserved2 = 0;
        header.bfOffBits = offBits;

        // Prepare core header
        BitmapCoreHeader core;
        core.biSize = 40;
        core.biWidth = _width;
        core.biHeight = -_height;
        core.biPlanes = 1;
        core.biBitCount = 24;
        core.biCompression = 0;
        core.biSizeImage = totalSize;
        core.biXPixPerMeter = 0;
        core.biYPixPerMeter = 0;
        core.biClrUsed = 0;
        core.biClrImportant = 0;

        std::ofstream ofs(filename.c_str(), std::ios::out | std::ios::binary);
        ofs.write((char*)&header, sizeof(BitmapFileHeader));
        ofs.write((char*)&core, sizeof(BitmapCoreHeader));

        char* lineBits = new char[lineSize];
        for (int y = 0; y < _height; y++) {
            memset(lineBits, 0, sizeof(char) * lineSize);
            char* ptr = lineBits;
            for (int x = 0; x < _width; x++) {
                int idx = y * _width + x;
                RGBTriple triple;
                triple.rgbRed = toByte(_pixels[idx].red());
                triple.rgbGreen = toByte(_pixels[idx].green());
                triple.rgbBlue = toByte(_pixels[idx].blue());
                memcpy(ptr, &triple, sizeof(RGBTriple));
                ptr += sizeof(RGBTriple);
            }
            ofs.write(lineBits, sizeof(char) * lineSize);
        }
        delete[] lineBits;

        ofs.close();
    }

    double Image::toReal(unsigned char b) {
        static const double gamma = 2.2;
        double d = b / 255.0;
        return pow(d, gamma);
    }

    unsigned char Image::toByte(double d) {
        static const double invgamma = 1.0 / 2.2;
        d = std::max(0.0, std::min(d, 1.0));
        return (unsigned char)(255.0 * pow(d, invgamma));
    }
}
<commit_msg>Revise long size misunderstanding.<commit_after>#define SPICA_IMAGE_EXPORT
#include "image.h"

#if defined(_WIN32) || defined(__WIN32__)
#define PACKED(__declare__) __pragma(pack(push,1)) __declare__ __pragma(pack(pop))
#else
#define PACKED(__declare__) __declare__ __attribute__((__packed__))
#endif

#include <cmath>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <algorithm>

#include "common.h"

namespace spica {

    namespace {
        PACKED(
        struct BitmapFileHeader {
            unsigned short bfType;
            unsigned int   bfSize;
            unsigned short bfReserved1;
            unsigned short bfReserved2;
            unsigned int   bfOffBits;
        });

        PACKED(
        struct BitmapCoreHeader {
            unsigned int   biSize;
            long biWidth;
            long biHeight;
            unsigned short biPlanes;
            unsigned short biBitCount;
            unsigned int   biCompression;
            unsigned int   biSizeImage;
            long biXPixPerMeter;
            long biYPixPerMeter;
            unsigned int  biClrUsed;
            unsigned int  biClrImportant;
        });

        PACKED(
        struct RGBTriple {
            unsigned char rgbBlue;
            unsigned char rgbGreen;
            unsigned char rgbRed;
        });
    }

    Image::Image()
        : _width(0)
        , _height(0)
        , _pixels(0)
    {
    }

    Image::Image(int width, int height)
        : _width(width)
        , _height(height)
        , _pixels(0)
    {
        msg_assert(width >= 0 && height >= 0, "Image size must be positive");
        _pixels = new Color[_width * _height];
    }

    Image::Image(const Image& image)
        : _width(image._width)
        , _height(image._height)
        , _pixels(new Color[image._width * image._height])
    {
        memcpy(_pixels, image._pixels, sizeof(Color) * image._width * image._height);
    }

    Image::~Image()
    {
        delete[] _pixels;
    }

    Image& Image::operator=(const Image& image) {
        delete[] _pixels;

        this->_width = image._width;
        this->_height = image._height;
        this->_pixels = new Color[image._width * image._height];
        memcpy(_pixels, image._pixels, sizeof(Color) * image._width * image._height);

        return *this;
    }

    const Color& Image::operator()(int x, int y) const {
        msg_assert(0 <= x && x < _width && 0 <= y && y < _height, "Pixel index out of bounds");
        return _pixels[y * _width + x];
    }

    Color& Image::pixel(int x, int y) {
        msg_assert(0 <= x && x < _width && 0 <= y && y < _height, "Pixel index out of bounds");
        return _pixels[y * _width + x];
    }

    void Image::loadBMP(const std::string& filename) {
        BitmapFileHeader header;
        BitmapCoreHeader core;

        printf("ho");
        std::ifstream ifs(filename.c_str(), std::ios::in | std::ios::binary);
        printf("ge\n");
        msg_assert(ifs.is_open(), "Failed to open file!!");

        ifs.read((char*)&header, sizeof(BitmapFileHeader));
        ifs.read((char*)&core, sizeof(BitmapCoreHeader));
        printf("header: %ld\n", sizeof(BitmapFileHeader));
        printf("  core: %ld\n", sizeof(BitmapCoreHeader));

        this->_width  = std::abs(core.biWidth);
        this->_height = std::abs(core.biHeight);
        this->_pixels = new Color[_width * _height];

        const int lineSize = (sizeof(RGBTriple) * _width + 3) / 4 * 4;
        char* lineBits = new char[lineSize];
        for (int y = 0; y < _height; y++) {
            ifs.read((char*)lineBits, lineSize);
            char* ptr = lineBits;
            for (int x = 0; x < _width; x++) {
                RGBTriple triple;
                memcpy(&triple, ptr, sizeof(RGBTriple));

                double red   = toReal(triple.rgbRed);
                double green = toReal(triple.rgbGreen);
                double blue  = toReal(triple.rgbBlue);
                this->_pixels[y * _width + x] = Color(red, green, blue);
                ptr += sizeof(RGBTriple);
            }
        }
        delete[] lineBits;

        ifs.close();
    }

    void Image::saveBMP(const std::string& filename) const {
        const int lineSize = (sizeof(RGBTriple) * _width + 3) / 4 * 4;
        const int totalSize = lineSize * _height;
        const int offBits = sizeof(BitmapFileHeader) + sizeof(BitmapCoreHeader);

        // Prepare file header
        BitmapFileHeader header;
        header.bfType = 'B' | ('M' << 8);
        header.bfSize = offBits + totalSize;
        header.bfReserved1 = 0;
        header.bfReserved2 = 0;
        header.bfOffBits = offBits;

        // Prepare core header
        BitmapCoreHeader core;
        core.biSize = 40;
        core.biWidth = _width;
        core.biHeight = -_height;
        core.biPlanes = 1;
        core.biBitCount = 24;
        core.biCompression = 0;
        core.biSizeImage = totalSize;
        core.biXPixPerMeter = 0;
        core.biYPixPerMeter = 0;
        core.biClrUsed = 0;
        core.biClrImportant = 0;

        std::ofstream ofs(filename.c_str(), std::ios::out | std::ios::binary);
        ofs.write((char*)&header, sizeof(BitmapFileHeader));
        ofs.write((char*)&core, sizeof(BitmapCoreHeader));

        char* lineBits = new char[lineSize];
        for (int y = 0; y < _height; y++) {
            memset(lineBits, 0, sizeof(char) * lineSize);
            char* ptr = lineBits;
            for (int x = 0; x < _width; x++) {
                int idx = y * _width + x;
                RGBTriple triple;
                triple.rgbRed = toByte(_pixels[idx].red());
                triple.rgbGreen = toByte(_pixels[idx].green());
                triple.rgbBlue = toByte(_pixels[idx].blue());
                memcpy(ptr, &triple, sizeof(RGBTriple));
                ptr += sizeof(RGBTriple);
            }
            ofs.write(lineBits, sizeof(char) * lineSize);
        }
        delete[] lineBits;

        ofs.close();
    }

    double Image::toReal(unsigned char b) {
        static const double gamma = 2.2;
        double d = b / 255.0;
        return pow(d, gamma);
    }

    unsigned char Image::toByte(double d) {
        static const double invgamma = 1.0 / 2.2;
        d = std::max(0.0, std::min(d, 1.0));
        return (unsigned char)(255.0 * pow(d, invgamma));
    }
}
<|endoftext|>


<commit_before>#include <vector>
#include <fstream>
#include <string>
#include <limits>
#include "scene.hpp"
#include "triangle.hpp"

class STLLoader {
public:
    static void populate(Scene& scene, const char* filename) {
        std::ifstream file(filename);
        std::string next;
        short count = 1;
        while (file >> next) {
            if (next == "loop") {
                std::vector<Point> vertices(3);
                for (int i = 0; i < 3; ++i) {
                    file >> next >> vertices[i].x >> vertices[i].y >> vertices[i].z;
                }
                scene.add_object(new Triangle(Color(count % 3, (count + 1) % 3, (count + 2) % 3), vertices[0], vertices[1], vertices[2]));
                ++count;
            }
        }
        scene.prepare();
    }
};
<commit_msg>remove debug colors<commit_after>#include <vector>
#include <fstream>
#include <string>
#include <limits>
#include "scene.hpp"
#include "triangle.hpp"

class STLLoader {
public:
    static void populate(Scene& scene, const char* filename) {
        std::ifstream file(filename);
        std::string next;
        short count = 1;
        while (file >> next) {
            if (next == "loop") {
                std::vector<Point> vertices(3);
                for (int i = 0; i < 3; ++i) {
                    file >> next >> vertices[i].x >> vertices[i].y >> vertices[i].z;
                }
                scene.add_object(new Triangle(Color(1, 1, 1), vertices[0], vertices[1], vertices[2]));
                ++count;
            }
        }
        scene.prepare();
    }
};
<|endoftext|>


<commit_before>/*
 * Copyright 2017-2018 Baidu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "openrasp_hook.h"
#include "openrasp_ini.h"
#include "openrasp_inject.h"
#include "openrasp_v8.h"
#include <new>
#include <map>
#include <algorithm>
#include "agent/shared_config_manager.h"
#include <unordered_map>
#include "openrasp_content_type.h"
#include "openrasp_check_type.h"

extern "C"
{
#include "ext/standard/php_fopen_wrappers.h"
}

using openrasp::OpenRASPContentType;

static hook_handler_t global_hook_handlers[512];
static size_t global_hook_handlers_len = 0;
static const std::string COLON_TWO_SLASHES = "://";

typedef struct _track_vars_pair_t
{
    int id;
    const char *name;
} track_vars_pair;

ZEND_DECLARE_MODULE_GLOBALS(openrasp_hook)

void register_hook_handler(hook_handler_t hook_handler)
{
    global_hook_handlers[global_hook_handlers_len++] = hook_handler;
}

const std::string get_check_type_name(OpenRASPCheckType type)
{
    return check_type_transfer->type_to_name(type);
}

bool openrasp_zval_in_request(zval *item)
{
    static const track_vars_pair pairs[] = {{TRACK_VARS_POST, "_POST"},
                                            {TRACK_VARS_GET, "_GET"},
                                            {TRACK_VARS_COOKIE, "_COOKIE"}};
    int size = sizeof(pairs) / sizeof(pairs[0]);
    for (int index = 0; index < size; ++index)
    {
        zval *global = &PG(http_globals)[pairs[index].id];
        if (Z_TYPE_P(global) != IS_ARRAY &&
            !zend_is_auto_global_str(const_cast<char *>(pairs[index].name), strlen(pairs[index].name)))
        {
            return false;
        }
        zval *val;
        ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(global), val)
        {
            if (Z_COUNTED_P(item) == Z_COUNTED_P(val))
            {
                return true;
            }
        }
        ZEND_HASH_FOREACH_END();
    }
    return false;
}

void openrasp_buildin_php_risk_handle(OpenRASPActionType action, OpenRASPCheckType type, int confidence, zval *params, zval *message)
{
    if (AC_IGNORE == action)
    {
        return;
    }
    zval params_result;
    array_init(&params_result);
    add_assoc_zval(&params_result, "attack_params", params);
    add_assoc_zval(&params_result, "plugin_message", message);
    add_assoc_long(&params_result, "plugin_confidence", confidence);
    add_assoc_string(&params_result, "attack_type", const_cast<char *>(get_check_type_name(type).c_str()));
    add_assoc_string(&params_result, "plugin_algorithm", const_cast<char *>(get_check_type_name(type).c_str()));
    add_assoc_string(&params_result, "intercept_state", const_cast<char *>(action_to_string(action).c_str()));
    add_assoc_string(&params_result, "plugin_name", const_cast<char *>("php_builtin_plugin"));
    LOG_G(alarm_logger).log(LEVEL_INFO, &params_result);
    zval_ptr_dtor(&params_result);
    if (AC_BLOCK == action)
    {
        handle_block();
    }
}

bool openrasp_check_type_ignored(OpenRASPCheckType check_type)
{
    if (!LOG_G(in_request_process))
    {
        return true;
    }
    if ((1 << check_type) & OPENRASP_HOOK_G(check_type_white_bit_mask))
    {
        return true;
    }
    if (check_type_transfer->is_buildin_check_type(check_type) &&
        openrasp::scm->get_buildin_check_action(check_type) == AC_IGNORE)
    {
        return true;
    }
    return false;
}

bool openrasp_check_callable_black(const char *item_name, uint item_name_length)
{
    std::vector<std::string> callable_blacklist =
        OPENRASP_CONFIG(webshell_callable.blacklist);

    return std::find(callable_blacklist.begin(),
                     callable_blacklist.end(),
                     std::string(item_name, item_name_length)) != callable_blacklist.end();
}

std::string openrasp_real_path(char *filename, int length, bool use_include_path, uint32_t w_op)
{
    std::string result;
    static const std::unordered_map<std::string, uint32_t> opMap = {
        {"http", READING},
        {"https", READING},
        {"ftp", READING | WRITING | APPENDING},
        {"ftps", READING | WRITING | APPENDING},
        {"php", READING | WRITING | APPENDING | SIMULTANEOUSRW},
        {"zlib", READING | WRITING | APPENDING},
        {"bzip2", READING | WRITING | APPENDING},
        {"zlib", READING},
        {"data", READING},
        {"phar", READING | WRITING | SIMULTANEOUSRW},
        {"ssh2", READING | WRITING | SIMULTANEOUSRW},
        {"rar", READING},
        {"ogg", READING | WRITING | APPENDING},
        {"expect", READING | WRITING | APPENDING}};
    if (!OPENRASP_CONFIG(plugin.filter))
    {
        w_op |= WRITING;
    }
    zend_string *resolved_path = nullptr;
    resolved_path = php_resolve_path(filename, length, use_include_path ? PG(include_path) : nullptr);
    if (nullptr == resolved_path)
    {
        const char *p = fetch_url_scheme(filename);
        if (nullptr != p)
        {
            php_stream_wrapper *wrapper;
            wrapper = php_stream_locate_url_wrapper(filename, nullptr, STREAM_LOCATE_WRAPPERS_ONLY);
            if (wrapper && wrapper->wops)
            {
                if (w_op & (RENAMESRC | RENAMEDEST))
                {
                    if (wrapper->wops->rename)
                    {
                        resolved_path = zend_string_init(filename, length, 0);
                    }
                }
                else if (w_op & OPENDIR)
                {
                    if (wrapper->wops->dir_opener)
                    {
                        resolved_path = zend_string_init(filename, length, 0);
                    }
                }
                else
                {
                    std::string scheme(filename, p - filename);
                    for (auto &ch : scheme)
                    {
                        ch = std::tolower(ch);
                    }
                    auto it = opMap.find(scheme);
                    if (it != opMap.end() && (w_op & it->second))
                    {
                        resolved_path = zend_string_init(filename, length, 0);
                    }
                }
            }
        }
        else
        {
            char expand_path[MAXPATHLEN];
            char real_path[MAXPATHLEN];
            expand_filepath(filename, expand_path);
            if (VCWD_REALPATH(expand_path, real_path))
            {
                if (w_op & (OPENDIR | RENAMESRC))
                {
                    //skip
                }
                else
                {
                    resolved_path = zend_string_init(expand_path, strlen(expand_path), 0);
                }
            }
            else
            {
                if (w_op & (WRITING | RENAMEDEST))
                {
                    resolved_path = zend_string_init(expand_path, strlen(expand_path), 0);
                }
            }
        }
    }
    if (resolved_path)
    {
        result = std::string(ZSTR_VAL(resolved_path), ZSTR_LEN(resolved_path));
        zend_string_release(resolved_path);
    }
    return result;
}

static std::string resolve_request_id(std::string str)
{
    static std::string placeholder = "%request_id%";
    std::string request_id = OPENRASP_INJECT_G(request_id);
    size_t start_pos = 0;
    while ((start_pos = str.find(placeholder, start_pos)) != std::string::npos)
    {
        str.replace(start_pos, placeholder.length(), request_id);
        start_pos += request_id.length();
    }
    return str;
}

void set_location_header()
{
    if (!SG(headers_sent))
    {
        std::string location = resolve_request_id("Location: " + OPENRASP_CONFIG(block.redirect_url));
        sapi_header_line header;
        header.line = const_cast<char *>(location.c_str());
        header.line_len = location.length();
        header.response_code = OPENRASP_CONFIG(block.status_code);
        sapi_header_op(SAPI_HEADER_REPLACE, &header);
    }
}

void handle_block()
{
    int status = php_output_get_status();
    if (status & PHP_OUTPUT_WRITTEN)
    {
        php_output_discard_all();
    }
    set_location_header();

    {
        OpenRASPContentType::ContentType k_type = OpenRASPContentType::ContentType::cNull;
        std::string existing_content_type;
        for (zend_llist_element *element = SG(sapi_headers).headers.head; element; element = element->next)
        {
            sapi_header_struct *sapi_header = (sapi_header_struct *)element->data;
            if (sapi_header->header_len > 0 &&
                strncasecmp(sapi_header->header, "content-type", sizeof("content-type") - 1) == 0)
            {
                existing_content_type = std::string(sapi_header->header);
                break;
            }
        }
        k_type = OpenRASPContentType::classify_content_type(existing_content_type);
        if (k_type == OpenRASPContentType::ContentType::cNull)
        {
            if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY ||
                zend_is_auto_global_str(ZEND_STRL("_SERVER")))
            {
                zval *z_accept = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), ZEND_STRL("HTTP_ACCEPT"));
                if (z_accept)
                {
                    std::string accept(Z_STRVAL_P(z_accept));
                    k_type = OpenRASPContentType::classify_accept(accept);
                }
            }
        }
        std::string content_type;
        std::string block_content;
        switch (k_type)
        {
        case OpenRASPContentType::ContentType::cApplicationJson:
            content_type = "Content-type: application/json";
            block_content = (OPENRASP_CONFIG(block.content_json));
            break;
        case OpenRASPContentType::ContentType::cApplicationXml:
            content_type = "Content-type: application/xml";
            block_content = (OPENRASP_CONFIG(block.content_xml));
            break;
        case OpenRASPContentType::ContentType::cTextXml:
            content_type = "Content-type: text/xml";
            block_content = (OPENRASP_CONFIG(block.content_xml));
            break;
        case OpenRASPContentType::ContentType::cTextHtml:
        case OpenRASPContentType::ContentType::cNull:
        default:
            content_type = "Content-type: text/html";
            block_content = (OPENRASP_CONFIG(block.content_html));
            break;
        }
        if (!block_content.empty())
        {
            std::string body = resolve_request_id(block_content);
            sapi_add_header(const_cast<char *>(content_type.c_str()), content_type.length(), 1);
            php_output_write(body.c_str(), body.length());
            php_output_flush();
        }
    }
    zend_bailout();
}

/**
 * 调用 openrasp_check 提供的方法进行检测
 * 若需要拦截，直接返回重定向信息，并终止请求
 */
void check(OpenRASPCheckType type, zval *params)
{
    bool result = false;
    openrasp::Isolate *isolate = OPENRASP_V8_G(isolate);
    if (LIKELY(isolate))
    {
        v8::HandleScope handlescope(isolate);
        auto v8_type = NewV8String(isolate, get_check_type_name(type));
        auto v8_params = v8::Local<v8::Object>::Cast(NewV8ValueFromZval(isolate, params));
        zval_ptr_dtor(params);
        result = isolate->Check(v8_type, v8_params, OPENRASP_CONFIG(plugin.timeout.millis));
    }
    if (result)
    {
        handle_block();
    }
}

extern int include_or_eval_handler(zend_execute_data *execute_data);
extern int echo_handler(zend_execute_data *execute_data);

PHP_GINIT_FUNCTION(openrasp_hook)
{
#ifdef ZTS
    new (openrasp_hook_globals) _zend_openrasp_hook_globals;
#endif
    openrasp_hook_globals->check_type_white_bit_mask = 0;
}

PHP_GSHUTDOWN_FUNCTION(openrasp_hook)
{
#ifdef ZTS
    openrasp_hook_globals->~_zend_openrasp_hook_globals();
#endif
}

PHP_MINIT_FUNCTION(openrasp_hook)
{
    ZEND_INIT_MODULE_GLOBALS(openrasp_hook, PHP_GINIT(openrasp_hook), PHP_GSHUTDOWN(openrasp_hook));

    for (size_t i = 0; i < global_hook_handlers_len; i++)
    {
        global_hook_handlers[i]();
    }

    zend_set_user_opcode_handler(ZEND_INCLUDE_OR_EVAL, include_or_eval_handler);
    zend_set_user_opcode_handler(ZEND_ECHO, echo_handler);
    return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(openrasp_hook)
{
    ZEND_SHUTDOWN_MODULE_GLOBALS(openrasp_hook, PHP_GSHUTDOWN(openrasp_hook));
    return SUCCESS;
}

PHP_RINIT_FUNCTION(openrasp_hook)
{
    if (openrasp::scm != nullptr)
    {
        char *url = fetch_outmost_string_from_ht(Z_ARRVAL_P(LOG_G(alarm_logger).get_common_info()), "url");
        if (url)
        {
            std::string url_str(url);
            std::size_t found = url_str.find(COLON_TWO_SLASHES);
            if (found != std::string::npos)
            {
                OPENRASP_HOOK_G(check_type_white_bit_mask) = openrasp::scm->get_check_type_white_bit_mask(url_str.substr(found + COLON_TWO_SLASHES.size()));
            }
        }
        if (!OPENRASP_HOOK_G(lru) ||
            OPENRASP_HOOK_G(lru)->max_size() != OPENRASP_CONFIG(lru.max_size))
        {
            OPENRASP_HOOK_G(lru) = new openrasp::LRU<std::string, bool>(OPENRASP_CONFIG(lru.max_size));
        }
    }
    return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(openrasp_hook);
<commit_msg>[PHP7]clear exceptions while block current request<commit_after>/*
 * Copyright 2017-2018 Baidu Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "openrasp_hook.h"
#include "openrasp_ini.h"
#include "openrasp_inject.h"
#include "openrasp_v8.h"
#include <new>
#include <map>
#include <algorithm>
#include "agent/shared_config_manager.h"
#include <unordered_map>
#include "openrasp_content_type.h"
#include "openrasp_check_type.h"

extern "C"
{
#include "Zend/zend_exceptions.h"
#include "ext/standard/php_fopen_wrappers.h"
}

using openrasp::OpenRASPContentType;

static hook_handler_t global_hook_handlers[512];
static size_t global_hook_handlers_len = 0;
static const std::string COLON_TWO_SLASHES = "://";

typedef struct _track_vars_pair_t
{
    int id;
    const char *name;
} track_vars_pair;

ZEND_DECLARE_MODULE_GLOBALS(openrasp_hook)

void register_hook_handler(hook_handler_t hook_handler)
{
    global_hook_handlers[global_hook_handlers_len++] = hook_handler;
}

const std::string get_check_type_name(OpenRASPCheckType type)
{
    return check_type_transfer->type_to_name(type);
}

bool openrasp_zval_in_request(zval *item)
{
    static const track_vars_pair pairs[] = {{TRACK_VARS_POST, "_POST"},
                                            {TRACK_VARS_GET, "_GET"},
                                            {TRACK_VARS_COOKIE, "_COOKIE"}};
    int size = sizeof(pairs) / sizeof(pairs[0]);
    for (int index = 0; index < size; ++index)
    {
        zval *global = &PG(http_globals)[pairs[index].id];
        if (Z_TYPE_P(global) != IS_ARRAY &&
            !zend_is_auto_global_str(const_cast<char *>(pairs[index].name), strlen(pairs[index].name)))
        {
            return false;
        }
        zval *val;
        ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(global), val)
        {
            if (Z_COUNTED_P(item) == Z_COUNTED_P(val))
            {
                return true;
            }
        }
        ZEND_HASH_FOREACH_END();
    }
    return false;
}

void openrasp_buildin_php_risk_handle(OpenRASPActionType action, OpenRASPCheckType type, int confidence, zval *params, zval *message)
{
    if (AC_IGNORE == action)
    {
        return;
    }
    zval params_result;
    array_init(&params_result);
    add_assoc_zval(&params_result, "attack_params", params);
    add_assoc_zval(&params_result, "plugin_message", message);
    add_assoc_long(&params_result, "plugin_confidence", confidence);
    add_assoc_string(&params_result, "attack_type", const_cast<char *>(get_check_type_name(type).c_str()));
    add_assoc_string(&params_result, "plugin_algorithm", const_cast<char *>(get_check_type_name(type).c_str()));
    add_assoc_string(&params_result, "intercept_state", const_cast<char *>(action_to_string(action).c_str()));
    add_assoc_string(&params_result, "plugin_name", const_cast<char *>("php_builtin_plugin"));
    LOG_G(alarm_logger).log(LEVEL_INFO, &params_result);
    zval_ptr_dtor(&params_result);
    if (AC_BLOCK == action)
    {
        handle_block();
    }
}

bool openrasp_check_type_ignored(OpenRASPCheckType check_type)
{
    if (!LOG_G(in_request_process))
    {
        return true;
    }
    if ((1 << check_type) & OPENRASP_HOOK_G(check_type_white_bit_mask))
    {
        return true;
    }
    if (check_type_transfer->is_buildin_check_type(check_type) &&
        openrasp::scm->get_buildin_check_action(check_type) == AC_IGNORE)
    {
        return true;
    }
    return false;
}

bool openrasp_check_callable_black(const char *item_name, uint item_name_length)
{
    std::vector<std::string> callable_blacklist =
        OPENRASP_CONFIG(webshell_callable.blacklist);

    return std::find(callable_blacklist.begin(),
                     callable_blacklist.end(),
                     std::string(item_name, item_name_length)) != callable_blacklist.end();
}

std::string openrasp_real_path(char *filename, int length, bool use_include_path, uint32_t w_op)
{
    std::string result;
    static const std::unordered_map<std::string, uint32_t> opMap = {
        {"http", READING},
        {"https", READING},
        {"ftp", READING | WRITING | APPENDING},
        {"ftps", READING | WRITING | APPENDING},
        {"php", READING | WRITING | APPENDING | SIMULTANEOUSRW},
        {"zlib", READING | WRITING | APPENDING},
        {"bzip2", READING | WRITING | APPENDING},
        {"zlib", READING},
        {"data", READING},
        {"phar", READING | WRITING | SIMULTANEOUSRW},
        {"ssh2", READING | WRITING | SIMULTANEOUSRW},
        {"rar", READING},
        {"ogg", READING | WRITING | APPENDING},
        {"expect", READING | WRITING | APPENDING}};
    if (!OPENRASP_CONFIG(plugin.filter))
    {
        w_op |= WRITING;
    }
    zend_string *resolved_path = nullptr;
    resolved_path = php_resolve_path(filename, length, use_include_path ? PG(include_path) : nullptr);
    if (nullptr == resolved_path)
    {
        const char *p = fetch_url_scheme(filename);
        if (nullptr != p)
        {
            php_stream_wrapper *wrapper;
            wrapper = php_stream_locate_url_wrapper(filename, nullptr, STREAM_LOCATE_WRAPPERS_ONLY);
            if (wrapper && wrapper->wops)
            {
                if (w_op & (RENAMESRC | RENAMEDEST))
                {
                    if (wrapper->wops->rename)
                    {
                        resolved_path = zend_string_init(filename, length, 0);
                    }
                }
                else if (w_op & OPENDIR)
                {
                    if (wrapper->wops->dir_opener)
                    {
                        resolved_path = zend_string_init(filename, length, 0);
                    }
                }
                else
                {
                    std::string scheme(filename, p - filename);
                    for (auto &ch : scheme)
                    {
                        ch = std::tolower(ch);
                    }
                    auto it = opMap.find(scheme);
                    if (it != opMap.end() && (w_op & it->second))
                    {
                        resolved_path = zend_string_init(filename, length, 0);
                    }
                }
            }
        }
        else
        {
            char expand_path[MAXPATHLEN];
            char real_path[MAXPATHLEN];
            expand_filepath(filename, expand_path);
            if (VCWD_REALPATH(expand_path, real_path))
            {
                if (w_op & (OPENDIR | RENAMESRC))
                {
                    //skip
                }
                else
                {
                    resolved_path = zend_string_init(expand_path, strlen(expand_path), 0);
                }
            }
            else
            {
                if (w_op & (WRITING | RENAMEDEST))
                {
                    resolved_path = zend_string_init(expand_path, strlen(expand_path), 0);
                }
            }
        }
    }
    if (resolved_path)
    {
        result = std::string(ZSTR_VAL(resolved_path), ZSTR_LEN(resolved_path));
        zend_string_release(resolved_path);
    }
    return result;
}

static std::string resolve_request_id(std::string str)
{
    static std::string placeholder = "%request_id%";
    std::string request_id = OPENRASP_INJECT_G(request_id);
    size_t start_pos = 0;
    while ((start_pos = str.find(placeholder, start_pos)) != std::string::npos)
    {
        str.replace(start_pos, placeholder.length(), request_id);
        start_pos += request_id.length();
    }
    return str;
}

void set_location_header()
{
    if (!SG(headers_sent))
    {
        std::string location = resolve_request_id("Location: " + OPENRASP_CONFIG(block.redirect_url));
        sapi_header_line header;
        header.line = const_cast<char *>(location.c_str());
        header.line_len = location.length();
        header.response_code = OPENRASP_CONFIG(block.status_code);
        sapi_header_op(SAPI_HEADER_REPLACE, &header);
    }
}

void handle_block()
{
    int status = php_output_get_status();
    if (status & PHP_OUTPUT_WRITTEN)
    {
        php_output_discard_all();
    }
    set_location_header();

    {
        OpenRASPContentType::ContentType k_type = OpenRASPContentType::ContentType::cNull;
        std::string existing_content_type;
        for (zend_llist_element *element = SG(sapi_headers).headers.head; element; element = element->next)
        {
            sapi_header_struct *sapi_header = (sapi_header_struct *)element->data;
            if (sapi_header->header_len > 0 &&
                strncasecmp(sapi_header->header, "content-type", sizeof("content-type") - 1) == 0)
            {
                existing_content_type = std::string(sapi_header->header);
                break;
            }
        }
        k_type = OpenRASPContentType::classify_content_type(existing_content_type);
        if (k_type == OpenRASPContentType::ContentType::cNull)
        {
            if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY ||
                zend_is_auto_global_str(ZEND_STRL("_SERVER")))
            {
                zval *z_accept = zend_hash_str_find(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER]), ZEND_STRL("HTTP_ACCEPT"));
                if (z_accept)
                {
                    std::string accept(Z_STRVAL_P(z_accept));
                    k_type = OpenRASPContentType::classify_accept(accept);
                }
            }
        }
        std::string content_type;
        std::string block_content;
        switch (k_type)
        {
        case OpenRASPContentType::ContentType::cApplicationJson:
            content_type = "Content-type: application/json";
            block_content = (OPENRASP_CONFIG(block.content_json));
            break;
        case OpenRASPContentType::ContentType::cApplicationXml:
            content_type = "Content-type: application/xml";
            block_content = (OPENRASP_CONFIG(block.content_xml));
            break;
        case OpenRASPContentType::ContentType::cTextXml:
            content_type = "Content-type: text/xml";
            block_content = (OPENRASP_CONFIG(block.content_xml));
            break;
        case OpenRASPContentType::ContentType::cTextHtml:
        case OpenRASPContentType::ContentType::cNull:
        default:
            content_type = "Content-type: text/html";
            block_content = (OPENRASP_CONFIG(block.content_html));
            break;
        }
        if (!block_content.empty())
        {
            std::string body = resolve_request_id(block_content);
            sapi_add_header(const_cast<char *>(content_type.c_str()), content_type.length(), 1);
            php_output_write(body.c_str(), body.length());
            php_output_flush();
        }
    }
    zend_clear_exception();
    zend_bailout();
}

/**
 * 调用 openrasp_check 提供的方法进行检测
 * 若需要拦截，直接返回重定向信息，并终止请求
 */
void check(OpenRASPCheckType type, zval *params)
{
    bool result = false;
    openrasp::Isolate *isolate = OPENRASP_V8_G(isolate);
    if (LIKELY(isolate))
    {
        v8::HandleScope handlescope(isolate);
        auto v8_type = NewV8String(isolate, get_check_type_name(type));
        auto v8_params = v8::Local<v8::Object>::Cast(NewV8ValueFromZval(isolate, params));
        zval_ptr_dtor(params);
        result = isolate->Check(v8_type, v8_params, OPENRASP_CONFIG(plugin.timeout.millis));
    }
    if (result)
    {
        handle_block();
    }
}

extern int include_or_eval_handler(zend_execute_data *execute_data);
extern int echo_handler(zend_execute_data *execute_data);

PHP_GINIT_FUNCTION(openrasp_hook)
{
#ifdef ZTS
    new (openrasp_hook_globals) _zend_openrasp_hook_globals;
#endif
    openrasp_hook_globals->check_type_white_bit_mask = 0;
}

PHP_GSHUTDOWN_FUNCTION(openrasp_hook)
{
#ifdef ZTS
    openrasp_hook_globals->~_zend_openrasp_hook_globals();
#endif
}

PHP_MINIT_FUNCTION(openrasp_hook)
{
    ZEND_INIT_MODULE_GLOBALS(openrasp_hook, PHP_GINIT(openrasp_hook), PHP_GSHUTDOWN(openrasp_hook));

    for (size_t i = 0; i < global_hook_handlers_len; i++)
    {
        global_hook_handlers[i]();
    }

    zend_set_user_opcode_handler(ZEND_INCLUDE_OR_EVAL, include_or_eval_handler);
    zend_set_user_opcode_handler(ZEND_ECHO, echo_handler);
    return SUCCESS;
}

PHP_MSHUTDOWN_FUNCTION(openrasp_hook)
{
    ZEND_SHUTDOWN_MODULE_GLOBALS(openrasp_hook, PHP_GSHUTDOWN(openrasp_hook));
    return SUCCESS;
}

PHP_RINIT_FUNCTION(openrasp_hook)
{
    if (openrasp::scm != nullptr)
    {
        char *url = fetch_outmost_string_from_ht(Z_ARRVAL_P(LOG_G(alarm_logger).get_common_info()), "url");
        if (url)
        {
            std::string url_str(url);
            std::size_t found = url_str.find(COLON_TWO_SLASHES);
            if (found != std::string::npos)
            {
                OPENRASP_HOOK_G(check_type_white_bit_mask) = openrasp::scm->get_check_type_white_bit_mask(url_str.substr(found + COLON_TWO_SLASHES.size()));
            }
        }
        if (!OPENRASP_HOOK_G(lru) ||
            OPENRASP_HOOK_G(lru)->max_size() != OPENRASP_CONFIG(lru.max_size))
        {
            OPENRASP_HOOK_G(lru) = new openrasp::LRU<std::string, bool>(OPENRASP_CONFIG(lru.max_size));
        }
    }
    return SUCCESS;
}

PHP_RSHUTDOWN_FUNCTION(openrasp_hook);
<|endoftext|>


<commit_before>/*******************************************************************************
    Taichi - Physically based Computer Graphics Library

    Copyright (c) 2017 Yuanming Hu <yuanmhu@gmail.com>

    All rights reserved. Use of this source code is governed by
    the MIT license as written in the LICENSE file.
*******************************************************************************/

#include <taichi/util.h>
#include <taichi/system/threading.h>
#include <csignal>
#include <spdlog/spdlog.h>

TC_NAMESPACE_BEGIN

void signal_handler(int signo);

#define TC_REGISTER_SIGNAL_HANDLER(name, handler)                    \
  {                                                                  \
    if (std::signal(name, handler) == SIG_ERR)                       \
      std::printf("Can not register signal handler for" #name "\n"); \
  }

Logger::Logger() {
  console = spdlog::stdout_color_mt("console");
  TC_LOG_SET_PATTERN("[%L %D %X.%e] %v")

  TC_REGISTER_SIGNAL_HANDLER(SIGSEGV, signal_handler);
  TC_REGISTER_SIGNAL_HANDLER(SIGABRT, signal_handler);
  TC_REGISTER_SIGNAL_HANDLER(SIGBUS, signal_handler);
  TC_REGISTER_SIGNAL_HANDLER(SIGFPE, signal_handler);
  spdlog::set_level(spdlog::level::trace);
  TC_TRACE("Taichi core started. Thread ID={}", PID::get_pid());
}

void Logger::trace(const std::string &s) {
  console->trace(s);
}

void Logger::debug(const std::string &s) {
  console->debug(s);
}

void Logger::info(const std::string &s) {
  console->info(s);
}

void Logger::warn(const std::string &s) {
  console->warn(s);
}
void Logger::error(const std::string &s, bool raise_signal) {
  console->error(s);
  if (raise_signal) {
    std::raise(SIGABRT);
  }
}
void Logger::critical(const std::string &s, bool raise_signal) {
  console->critical(s);
  if (raise_signal) {
    std::raise(SIGABRT);
  }
}
void Logger::flush() {
  console->flush();
}

Logger logger;

void signal_handler(int signo) {
  logger.error(fmt::format("Received signal {} ({})", signo, strsignal(signo)),
               false);
  TC_FLUSH_LOGGER;
  taichi::print_traceback();
  if (taichi::CoreState::get_instance().python_imported) {
    std::string msg =
        fmt::format("Taichi Core Exception: {} ({})", signo, strsignal(signo));
    taichi_raise_assertion_failure_in_python(msg.c_str());
  }
  std::exit(-1);
}

TC_NAMESPACE_END
<commit_msg>space before thread id<commit_after>/*******************************************************************************
    Taichi - Physically based Computer Graphics Library

    Copyright (c) 2017 Yuanming Hu <yuanmhu@gmail.com>

    All rights reserved. Use of this source code is governed by
    the MIT license as written in the LICENSE file.
*******************************************************************************/

#include <taichi/util.h>
#include <taichi/system/threading.h>
#include <csignal>
#include <spdlog/spdlog.h>

TC_NAMESPACE_BEGIN

void signal_handler(int signo);

#define TC_REGISTER_SIGNAL_HANDLER(name, handler)                    \
  {                                                                  \
    if (std::signal(name, handler) == SIG_ERR)                       \
      std::printf("Can not register signal handler for" #name "\n"); \
  }

Logger::Logger() {
  console = spdlog::stdout_color_mt("console");
  TC_LOG_SET_PATTERN("[%L %D %X.%e] %v")

  TC_REGISTER_SIGNAL_HANDLER(SIGSEGV, signal_handler);
  TC_REGISTER_SIGNAL_HANDLER(SIGABRT, signal_handler);
  TC_REGISTER_SIGNAL_HANDLER(SIGBUS, signal_handler);
  TC_REGISTER_SIGNAL_HANDLER(SIGFPE, signal_handler);
  spdlog::set_level(spdlog::level::trace);
  TC_TRACE("Taichi core started. Thread ID = {}", PID::get_pid());
}

void Logger::trace(const std::string &s) {
  console->trace(s);
}

void Logger::debug(const std::string &s) {
  console->debug(s);
}

void Logger::info(const std::string &s) {
  console->info(s);
}

void Logger::warn(const std::string &s) {
  console->warn(s);
}
void Logger::error(const std::string &s, bool raise_signal) {
  console->error(s);
  if (raise_signal) {
    std::raise(SIGABRT);
  }
}
void Logger::critical(const std::string &s, bool raise_signal) {
  console->critical(s);
  if (raise_signal) {
    std::raise(SIGABRT);
  }
}
void Logger::flush() {
  console->flush();
}

Logger logger;

void signal_handler(int signo) {
  logger.error(fmt::format("Received signal {} ({})", signo, strsignal(signo)),
               false);
  TC_FLUSH_LOGGER;
  taichi::print_traceback();
  if (taichi::CoreState::get_instance().python_imported) {
    std::string msg =
        fmt::format("Taichi Core Exception: {} ({})", signo, strsignal(signo));
    taichi_raise_assertion_failure_in_python(msg.c_str());
  }
  std::exit(-1);
}

TC_NAMESPACE_END
<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright (C) 2015 Sahil Kang <sahil.kang@asilaycomputing.com>
 *
 * This file is part of gurpy.
 *
 * gurpy is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gurpy is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with gurpy.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include <Python.h>
#include <gur.hpp>

template<typename T>
PyObject* tuple_of_word(PyObject *args, T method)
{
	const char* str;
	if (!PyArg_ParseTuple(args, "s", &str))
	{
		return NULL;
	}

	gur::Word word = (gur::Word(str).*method)();
	PyObject *py_word = PyTuple_New(word.size());

	for (std::size_t i = 0; i != word.size(); ++i)
	{
		PyTuple_SetItem(py_word, i, PyUnicode_FromString(
			word[i].str().c_str()));
	}

	return py_word;
}

static PyObject* gp_letters(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::letters);
}

static PyObject* gp_accents(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::accents);
}

static PyObject* gp_puncs(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::punctuations);
}

static PyObject* gp_digits(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::digits);
}

static PyObject* gp_symbols(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::symbols);
}

static PyObject* gp_comp(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::composition);
}

static PyMethodDef gp_methods[] =
{
	{"letters", gp_letters, METH_VARARGS, "Get the letters in a word."},
	{"accents", gp_accents, METH_VARARGS, "Get the accents in a word."},
	{"puncs", gp_puncs, METH_VARARGS, "Get the punctuations in a word."},
	{"digits", gp_digits, METH_VARARGS, "Get the digits in a word."},
	{"symbols", gp_symbols, METH_VARARGS, "Get the symbols in a word."},
	{"comp", gp_comp, METH_VARARGS, "Get a word's composition."},
	{NULL, NULL, 0, NULL}
};

static struct PyModuleDef gp_module =
{
	PyModuleDef_HEAD_INIT,
	"gurpy", //name of the module
	"Python extension for libgur", //module doc
	-1,
	gp_methods
};

PyMODINIT_FUNC PyInit_gurpy(void)
{
	return PyModule_Create(&gp_module);
}
<commit_msg>Add clobber and unclobber functions<commit_after>/******************************************************************************
 * Copyright (C) 2015 Sahil Kang <sahil.kang@asilaycomputing.com>
 *
 * This file is part of gurpy.
 *
 * gurpy is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * gurpy is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with gurpy.  If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include <Python.h>
#include <gur.hpp>
#include <sstream>

template<typename T>
PyObject* tuple_of_word(PyObject *args, T method)
{
	const char* str;
	if (!PyArg_ParseTuple(args, "s", &str))
	{
		return NULL;
	}

	gur::Word word = (gur::Word(str).*method)();
	PyObject *py_word = PyTuple_New(word.size());

	for (std::size_t i = 0; i != word.size(); ++i)
	{
		PyTuple_SetItem(py_word, i, PyUnicode_FromString(
			word[i].str().c_str()));
	}

	return py_word;
}

static PyObject* gp_letters(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::letters);
}

static PyObject* gp_accents(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::accents);
}

static PyObject* gp_puncs(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::punctuations);
}

static PyObject* gp_digits(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::digits);
}

static PyObject* gp_symbols(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::symbols);
}

static PyObject* gp_comp(PyObject *self, PyObject *args)
{
	return tuple_of_word(args, &gur::Word::composition);
}

static PyObject* gp_clobber(PyObject *self, PyObject *args)
{
	const char* str;
	if (!PyArg_ParseTuple(args, "s", &str))
	{
		return NULL;
	}

	gur::Word word(str);
	std::ostringstream oss;
	oss << word;

	return PyUnicode_FromString(oss.str().c_str());
}

static PyObject* gp_unclobber(PyObject *self, PyObject *args)
{
	const char* str;
	if (!PyArg_ParseTuple(args, "s", &str))
	{
		return NULL;
	}

	gur::Word word(str);
	std::ostringstream oss(std::ostringstream::ate);

	for (auto &c : word)
	{
		oss << c;
	}

	return PyUnicode_FromString(oss.str().c_str());
}

static PyMethodDef gp_methods[] =
{
	{"letters", gp_letters, METH_VARARGS, "Get the letters in a word."},
	{"accents", gp_accents, METH_VARARGS, "Get the accents in a word."},
	{"puncs", gp_puncs, METH_VARARGS, "Get the punctuations in a word."},
	{"digits", gp_digits, METH_VARARGS, "Get the digits in a word."},
	{"symbols", gp_symbols, METH_VARARGS, "Get the symbols in a word."},
	{"comp", gp_comp, METH_VARARGS, "Get a word's composition."},
	{"clobber", gp_clobber, METH_VARARGS, "Combine diacritics."},
	{"unclobber", gp_unclobber, METH_VARARGS, "Separate diacritics."},
	{NULL, NULL, 0, NULL}
};

static struct PyModuleDef gp_module =
{
	PyModuleDef_HEAD_INIT,
	"gurpy", //name of the module
	"Python extension for libgur", //module doc
	-1,
	gp_methods
};

PyMODINIT_FUNC PyInit_gurpy(void)
{
	return PyModule_Create(&gp_module);
}
<|endoftext|>