!C99Shell v. 2.0 [PHP 7 Update] [25.02.2019]!

Software: nginx/1.23.4. PHP/5.6.40-65+ubuntu20.04.1+deb.sury.org+1 

uname -a: Linux foro-restaurado-2 5.15.0-1040-oracle #46-Ubuntu SMP Fri Jul 14 21:47:21 UTC 2023
aarch64
 

uid=33(www-data) gid=33(www-data) groups=33(www-data) 

Safe-mode: OFF (not secure)

/home/scripts/pba/phc-read-only/src/ast_to_hir/   drwxrwxr-x
Free 83.21 GB of 96.73 GB (86.02%)
Home    Back    Forward    UPDIR    Refresh    Search    Buffer    Encoder    Tools    Proc.    FTP brute    Sec.    SQL    PHP-code    Update    Feedback    Self remove    Logout    


Viewing file:     AST_shredder.cpp (8.41 KB)      -rw-rw-r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/*
 * phc -- the open source PHP compiler
 * See doc/license/README.license for licensing information
 *
 * shredder (n.): a machine that tears objects into smaller pieces.
 * Transform the AST into 3AC-like code.
 */

#include "AST_annotate.h"
#include "AST_shredder.h"
#include "process_ir/General.h"

using namespace AST;

void Shredder::children_php_script(PHP_script* in)
{
    Annotate ann;
    in->visit(&ann);

    Lower_expr::children_php_script(in);
}

/*
 * Variables (array indexing, object indexing)
 *
 * We do the indexing bit-by-bit. For example, for $c->a[1][2][3], we get
 *
 *    $T0 =& $c->arr;
 *    $T1 =& $T0[1];
 *    $T2 =& $T1[2];
 *    $T2[3] ... ;
 *
 * However, we always stop one short, as in $T2 above. This is necessary in the
 * case of unset, returning by reference, and a number of other cases.
 *
 * Note that it is important to use reference assignment, because when we
 * assign to $T2[2] above, we want the original object $c to be modified.
 *
 * However, introducing references where there were no references before will
 * result in an element being inserted in the array if the element is
 * missing, or the array is NULL. For example,
 *
 *        $x = $y[5];
 *
 *    is different than
 *
 *        $x =& $y[5];
 *
 *    since $y has no index 5.
 *
 * As a result, we use reference assignment only if there is an implicit
 * reference, or reference assignment is used.
 */

Variable* Shredder::post_variable(Variable* in)
{
    if (in->attrs->is_true ("phc.ast_shredder.dont_shred"))
        return in;

    Variable* prev = in;
    
    int num_pieces = 
          (in->target != NULL ? 1 : 0) 
        + in->array_indices->size()
        - (in->attrs->is_true("phc.ast_shredder.need_addr") ? 1 : 0);

    // translate ${$x}[1] to $T =& ${$x}; $T[1] but only if no target is set
    if(in->target == NULL 
        && in->variable_name->classid() == Reflection::ID
        && !in->attrs->is_true ("phc.ast_lower_expr.no_temp"))
    {
        Variable* temp = fresh_var("TSr");

        pieces->push_back(
            new Eval_expr(
                new Assignment(
                    temp->clone (), 
                    in->attrs->is_true ("phc.ast_shredder.use_ref"),
                    new Variable (in->variable_name))));

        prev = temp;
    }

    if(in->target != NULL && num_pieces > 0)
    {
        Variable* temp = fresh_var("TSt");
        pieces->push_back(new Eval_expr(new Assignment(
            temp->clone (),
            in->attrs->is_true ("phc.ast_shredder.use_ref"),
            new Variable (
                in->target,
                in->variable_name->clone(),
                new Expr_list
            ))));
        prev = temp;
        num_pieces--;

        // TODO: this destructively modifies *in. is that what we want?
        in->target = NULL;
    }

    while(num_pieces > 0)
    {
        // Get the array index (can be NULL)
        Expr* array_index = in->array_indices->front ();
        if (array_index)
            array_index = array_index->clone ();
        // TODO: this destructively modifies *in. is that what we want?
        in->array_indices->pop_front();


        Variable* temp = fresh_var("TSi");
        pieces->push_back(new Eval_expr(new Assignment(
            temp->clone (),
            in->attrs->is_true ("phc.ast_shredder.use_ref"),
            new Variable (
                NULL, 
                prev->variable_name->clone(), 
                new Expr_list (array_index)))));
        prev = temp;
        num_pieces--;
    }

    if(prev != in && !in->array_indices->empty())
    {
        prev = prev->clone();
        Expr* front = in->array_indices->front();
        in->array_indices->pop_front();

        if (front) // NULL expressions are allowed
            front = front->clone ();

        prev->array_indices->push_back(front);
    }

    return prev;
}

/*
 * Binary and unary operators
 *
 * The "lazy" binary operators (&&, ||, and friends) are not dealt with here, 
 * but in the lowering pass. Pre and post operators are handled in Early_Shredder.
 */

Expr* Shredder::post_bin_op(Bin_op* in)
{
    return eval(in);
}

Expr* Shredder::post_unary_op(Unary_op* in)
{
    return eval(in);
}

/*
 * Casts
 */

Expr* Shredder::post_cast(Cast* in)
{
    return eval(in);
}

/*
 * instanceof
 */

Expr* Shredder::post_instanceof (Instanceof* in)
{
    return eval(in);
}

/*
 * Method invocation
 */

Expr* Shredder::post_method_invocation(Method_invocation* in)
{
    return eval(in);
}

Expr* Shredder::post_new (New* in)
{
    return eval(in);
}

/*
 * Literals
 */

/* In most cases, it isnt required to shred literals, but it simplifies matters
 * a great deal. If we don't shred these, then we need to simplify reflections
 * and branches with immediate values, run a constant-folding pass after
 * switch-lowering, remove literals in statements by themselves, and allow the
 * unparser to print unprintable variables (like $5 or ${""}). All of these
 * changes would then have to be duplicated in the MIR. It is simpler to shred
 * here, and just make the changes in the MIR. */

Expr* Shredder::post_int(INT* in)
{
    return eval(in);
}

Expr* Shredder::post_real(REAL* in)
{
    return eval(in);
}

Expr* Shredder::post_string(STRING* in)
{
    return eval(in);
}

Expr* Shredder::post_bool(BOOL* in)
{
    return eval(in);
}

Expr* Shredder::post_nil(NIL* in)
{
    return eval(in);
}

Expr* Shredder::post_constant (Constant* in)
{
    return eval(in);
}

/*
 * Translate into canonical tree form (replace assignments within expressions
 * with an assignment and a variable access:
 *
 * Translate
 *
 *      $x = $y = 5;
 *
 *    into
 *
 *      $y = 5;
 *      $t1 = $y;
 *      $x = $t1;
 */
Expr* Shredder::post_assignment (Assignment* in)
{
    if (in->attrs->is_true ("phc.ast_shredder.non_nested_assignment"))
        return in;

    // dont replace with the same variable, since it may be assigned to multiple
    // times in the same expression.
    pieces->push_back (new Eval_expr (in));
    return eval (in->variable);
}

/*
 * Array literals
 */

Expr* Shredder::post_array(Array* in)
{
    if (in->attrs->is_true("phc.ast_lower_expr.no_temp"))
        return in;

    Variable* var = fresh_var ("TSa");

    // We need to unset TS in case its run in a loop
    pieces->push_back(new Eval_expr(new Method_invocation("unset", var->clone ())));

    // We need to cast it in case its empty
    pieces->push_back(
        new Eval_expr (
            new Assignment (
                var->clone (), 
                false, 
                new Cast(
                    "array", 
                    new String ("array"), 
                    var->clone ()))));


    // It makes it much much easier to analyse if we don't throw this
    // information away. A key without an index uses the next largest key. 
    int key_count = 0;
    bool use_count = true;
    foreach (Array_elem* ae, *in->array_elems)
    {
        Expr* key;

        if(ae->key != NULL)
        {
            key = ae->key;

            // This disrupts the count (we could carry on, but it'll only helpful
            // in rare occasions).
            use_count = false;
        }
        else if (use_count)
        {
            key = new INT (key_count);
            key_count++;
        }
        else
            key = NULL;

        pieces->push_back(
            new Eval_expr(
                new Assignment(
                    new Variable (
                        NULL,
                        var->variable_name->clone(),
                        new Expr_list (key)),
                    ae->is_ref,
                    ae->val)));
    }

    return new Variable (var->variable_name->clone ());
}

/* Turn
 *
 *        $x[...] += $y;
 *
 *    into
 *
 *        $T &= $x[...]
 *        $T = $T + $y;
 *
 *    If $x is a simple variable, simply turn into
 *
 *        $x = $x + $y;
 */
Expr* Shredder::post_op_assignment(Op_assignment* in)
{
    Assignment* assignment;

    // The LHS may be of the form $x[$y], but that should occur
    // as an operand to a binary operator. Hence, we must visit the RHS again
    // clearing the need_addr flag
    in->variable->attrs->erase("phc.ast_shredder.need_addr");

    Variable* lhs = in->variable;
    // If not a simple varaible, then $lhs &= $x[...];
    if (!lhs->is_simple_variable ())
    {
        lhs = fresh_var ("Toa");
        Expr* copy = new Assignment (
                lhs->clone (),
                true,
                in->variable);

        copy->transform_children (this);
        pieces->push_back (new Eval_expr (copy));
    }

    // Create $T = $T + $y;
    assignment = new Assignment(
        lhs,
        false,
        new Bin_op (
            lhs->clone (),
            in->op, 
            in->expr));

    assignment->attrs = in->attrs;

    // This might still be nested assignment
    return post_assignment (assignment);
}

Expr* Shredder::pre_ignore_errors(Ignore_errors* in)
{
    Variable* zero = fresh_var("TSie");
    Variable* temp = fresh_var("TSie");
    pieces->push_back(new Eval_expr(new Assignment(
        zero,
        false,
        new INT(0))));
    pieces->push_back(new Eval_expr(new Assignment(
        temp,
        false,
        new Method_invocation(
            "error_reporting",
            zero->clone ()))));
    in->attrs->set("phc.ast_shredder.old_error_level", temp->clone ());
    return in;
}

Expr* Shredder::post_ignore_errors(Ignore_errors* in)
{
    Variable* temp = fresh_var("TSie");
    Variable* old = dynamic_cast<Variable*>(in->attrs->get("phc.ast_shredder.old_error_level"));
    in->attrs->erase ("phc.ast_shredder.old_error_level");
    assert(old);
    
    (*pieces
        << temp << " = error_reporting (" << old << ");"
    ).finish (in);

    return in->expr;
}

:: Command execute ::

Enter:
 
Select:
 

:: Search ::
  - regexp 

:: Upload ::
 
[ Read-Only ]

:: Make Dir ::
 
[ Read-Only ]
:: Make File ::
 
[ Read-Only ]

:: Go Dir ::
 
:: Go File ::
 

--[ c99shell v. 2.0 [PHP 7 Update] [25.02.2019] maintained by HackingTool | HackingTool | Generation time: 0.0057 ]--