## DEV Community 👩‍💻👨‍💻 # Introduction

Welcome to the second part of the Returntrue.win writeup!

Hopefully you already did read and understand the first half of those challenge. While not required, it is recommended to read it Here first!

Now is the time to stop reading and try to solve the challenges yourself before reading on the solutions!

Website: https://returntrue.win

## Level 9

#### Challenge

``````function foo(\$x)
{
\$y = \$x + 1;
return ++\$x != \$y;
}
``````

#### Solution

``````foo(x);
``````

#### Explanation

The solution here is lies in how PHP implemented the increment operator.

While you might expect `++\$x` to convert `\$x` to a number before converting it, it actually will return the next character in the alphabet.

In our case, `++\$x` is equal to `y` as it is the next letter following `x`,
`\$y` will be a number, aka. `1`, as it is the result of an addition.

The final comparison therefore is `'y' != 1`, which is true!

## Level 10

#### Challenge

``````class Bar
{
private \$a;

public function __construct(\$a)
{
\$this->a = (bool) \$a;
}

public function a()
{
return \$this->a;
}
}

function foo(callable \$x)
{
\$object = new Bar(false);
\$x(\$object);
return \$object->a();
}
``````

#### Solution

``````foo(function(&\$a){\$a=new\$a(1);});
``````

#### Explanation

This one is tricky, and fun!

Here is how the long, unminified, version of the answer might look like:

``````foo(function(&\$barInstance) {
\$barInstance = new Bar(true);
});
``````

As we are given `\$object` as argument in our function, using it as a reference lets us modify it.

We can't easily modify the `a` property of this object as it is private, but we can reassign the variable to be a new instance of Bar!

The minified version uses few tricks to shorten the payload:

• Use `1` instead of `true` in the constructor, which works as the `Bar` constructor casts the element to a boolean
• Create a new instance of a class from an instance, as documented here
• Remove all unnecessary spaces and indentation

The most interesting part of the shortest payload here is the creation of a new `Bar` instance using `new \$a(1)`, which I didn't know about before reading the solutions!

## Level 11

#### Challenge

``````function foo(array \$x)
{
return \$x === null;
}
``````

#### Solution

``````foo([]);
``````

#### Explanation

Arrays undefined offset will return null if accessed, therefore an empty array will pass this check.

## Level 12

#### Challenge

``````function foo(\$x)
{
return \$x !== null
&& \$x === \$x;
}
``````

#### Solution

``````foo(x);
``````

#### Explanation

This may seem weird at first, but the answer is to pass any string.

Accessing an invalid char index on a string will return an empty string `''`, which passes all conditions.

It is equivalent to the following array, with additional notices printed out:
`[123456 => '', '']`

##### Reference:

StackOverflow: Finding the next numeric index of an array

## Level 13

#### Challenge

``````class Test
{
private \$foo = true;
}

function foo(\$x)
{
\$o = (array) new Test;
return \$o[\$x];
}
``````

#### Solution

``````foo("\00Test\00foo");
``````

#### Explanation

The solution resides in knowing how array casting works.

The keys are the member variable names, with a few notable exceptions:

[...] private variables have the class name prepended to the variable name;

[...] These prepended values have null bytes on either side.

As `foo` is a private property of `Test`, its array key is `Testfoo` with nullbytes before `Test` and `foo`.

To obtain the shortest score of 11, you need to replace both escaped nullbytes `\00` with a real nullbyte in the POSTed request.

I'll leave this as a challenge to the reader!

## Level 14

#### Challenge

``````function foo(\$x)
{
return is_object(\$x) && is_object(\$x());
}
``````

#### Solution

``````foo(function(){yield;});
``````

#### Explanation

The solution is simple once explained, but really tricky to find out.

The first required knowledge is that anonymous functions are represented by the Closure class in PHP.

This lets us pass the first `is_object(\$x)` using less characters than creating a callable object.

The second required knowledge is PHP's generators.

The `yield` keyword returns a Generator, which can be used to continue the execution later on.

This leads us to this very short 18 characters solution!

## Level 15

#### Challenge

``````function foo(\$value)
{
return \$value != \$value;
}
``````

#### Solution

``````foo(NAN);
``````

#### Explanation

The NAN constant is not equal to itself due the IEEE754 spec.

More details on this stackoverflow question.

## Level 16

#### Challenge

``````function foo(\$x)
{
// This level is slightly different than level 12
// the comparison is != instead of !== ;)
return \$x != null
&& \$x === \$x;
}
``````

#### Solution

``````foo([123456=>1,1]);
``````

#### Explanation

Unlike challenge 12, the loose equality comparison does not let us use a string to pass the first condition.

The reason why this solution works is that PHP increments the last inserted numeric key to create its next values.

In this case, as the first inserted key is `123456`, the second one will be `123457`, both having the value of 1.

# Conclusion

Those were lots of original solutions to the challenge!
Most of those solutions did produce warnings and notices, therefore most of the odd behavior should be detected in a proper development environment.

Like on my previous blog post, I would like to thank:

If you do know similar oddities or challenge websites, please do send them my way so I can solve and write about them!

# References  