1

I am having trouble with NSProcessInfo's arguments property. I am creating a command line tool that needs to decode base64 code that it has been passed from the internet using a PHP script, along with some other arguments. The data is passed fine, but for some reason. [[NSProcessInfo processInfo] arguments] returns 21 arguments, even though I pass just one base64 string.

Here's the objective-c side of it:

NSArray *arguments = [[NSProcessInfo processInfo] arguments];

if ([[arguments objectAtIndex:1] isEqualToString:@"-s"])
{
    if ([arguments objectAtIndex:2] == nil)
    {
        printf("Error: No data\n");
        [pool drain];
        return 0;
    }

    NSString*data = [arguments objectAtIndex:2];

    if ([data length] == 0)
    {
        printf("Error: No data\n");
        [pool drain];
        return 0;
    }

    NSString*password = @"";

    if ([[arguments objectAtIndex:3] isEqualToString:@"-p"])
    {
        if ([arguments objectAtIndex:4] == nil)
        {
            printf("Error: No password\n");
            [pool drain];
            return 0;
        }
        else
        {
            password = [NSString stringWithString:[arguments lastObject]];
        }
    }

NSLog(@"Args: %i\n\n",[arguments count]); //returns 21? I expect 3.

The base64 code is a bit long, so I've put it here. Does anyone know why this code returns this many arguments? It's supposed to be just one string? Edit: I am stripping whitespaces in my PHP script. See here:

<?php

$url = $_GET['data'];

$query = "/Library/WebServer/email/emailsender -s";
$password = "-p somePassword";

$commandStr = trim("$query $url $password");

$commandStr = removeNewLines($commandStr);

echo $commandStr;

$output = shell_exec($commandStr);

echo "<pre>Output: $output</pre>";

function removeNewLines($string) {

    $string = str_replace( "\t", ' ', $string );
    $string = str_replace( "\n", ' ', $string );
    $string = str_replace( "\r", ' ', $string );
    $string = str_replace( "\0", ' ', $string );
    $string = str_replace( "\x0B", ' ', $string );

    return $string;

}

?>
Pripyat
  • 2,937
  • 2
  • 35
  • 69
  • You might want to `NSLog(@"%@", arguments)` so you see exactly what your program got. There is a possibility that your problem immediately becomes obvious. First, there are 13 whitespace characters in your base64 string, which, automatically, makes up for at least 14 arguments. (You have to quote your base64 data if you want it to be treated as a single argument.) – zneak Jul 10 '11 at 18:21
  • I already did that before posting here. It shows an array with the `base64` code broken up into 18 parts. – Pripyat Jul 10 '11 at 18:23
  • then maybe you could share the results :) – zneak Jul 10 '11 at 18:25
  • `trim` removes whitespaces at the beginning and at the end of a string; is it really what you mean? – zneak Jul 10 '11 at 18:26
  • @Zneak - You are my hero. Putting it into quotation marks did the trick. Please post it as an answer so I can mark it as the correct one. – Pripyat Jul 10 '11 at 18:28

2 Answers2

2

When I display the Base64 string on your pastie page as "raw" I see a lot of spaces in it. So most likely the arguments is correct and your PHP script is calling the Objective-C program the wrong way. An easy fix might be to just strip out any whitespace before passing the string, or properly escape it.

DarkDust
  • 90,870
  • 19
  • 190
  • 224
  • @David Schiefer: No, you're replacing things like newline and tabs with *spaces*, and that's the problem. According to the question [How do I to properly handle spaces in PHP Shell_exec?](http://stackoverflow.com/questions/378490/how-do-i-to-properly-handle-spaces-in-php-shell-exec) you should use `escapeshellarg` to escape the string (or replace your `' '` with `''` in your calls to `str_replace`). – DarkDust Jul 10 '11 at 18:30
  • Just putting it into quotation marks did the trick. But I'll mark this as +1 for the effort. Thanks! :) – Pripyat Jul 10 '11 at 18:31
  • @David Schiefer: Alright, but keep in mind that if your string could contain things like quotation marks, dollar signs or similar characters you should use `escapeshellarg` instead. – DarkDust Jul 10 '11 at 18:35
2

When you send arguments to a program through the command-line, each argument is separated by a whitespace character. This means that if you post a string that contains spaces, your program will interpret it as many arguments. To prevent this behavior, you need to quote your strings.

zneak
  • 134,922
  • 42
  • 253
  • 328