0
    if($_SERVER['REQUEST_METHOD']==='POST') {

    // get post data
    foreach(array_keys($_POST) as $key){

        $value=$_POST[$key];

        // $data[$key]=$value;

        if(preg_match('/_/',$key)){
            $key1=preg_replace('/\_/',' ',$key);
            $substitute=1;
        }
        else{
            $substitute=0;
        }

        // experimental, broken, returns non-utf8
        // for multiple selects etc.
        if(is_array($value)){
            $data[$key]=array();
            if($substitute){
                $data[$key1]=array();
            }
            foreach($value as $entry){
                $entry=stripslashes($entry);
                if($substitute){
                    array_push($data[$key1],$entry);
                }
                array_push($data[$key],$entry);
            }
        }
        else{
            $value=stripslashes($value);

            if($substitute){
                $data[$key1]=$value;
            }
            $data[$key]=$value;
        }
         // utf8_decode($post_data);
        $post_data=http_build_query($data);
    }

    // $data=preg_replace('/\&$/','',$data);



    // call url and pass POST data
    $page=do_post_request($url,$data,$user_login);
    // $page=utf8_decode($page);

    header('Content-Type:text/html; charset=utf-8');

    if(preg_match('/aspdf\=true/',$url)){
        output_pdf($page['content']);
    }
    else{
        print($page);
    }
}

I have a slightly complex problem. This php script (snippet of) sends post data to a perl cgi script via CURL, which mostly works fine EXCEPT for Multiple Select Data. The only way to make Multiple Select Data (i.e. requiring a nested array which CURL will not accept in the POST field) accepted is to flatten it and use a query string. Hey great! except... UTF8 data gets mangled in the process - it CANNOT be simply fixed buy using utf8_decode (well, it APPEARS to except the data received by the Perl CGI script is corrupted so that even though the return result and output of the php looks fine my Perl interface & data source is messed up - it works in all utf8 fine so the Perl script is not the problem). Tried forcing curl to use multipart instead of x-www that just died...

I have researched lots of other threads on this topic here already, they all suggest flattening the array which will NOT work for me unless there is a way round this utf8 problem, or they suggest using utf_decode which as I say leaves me corrupt data.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Beeblbrox
  • 351
  • 1
  • 11
  • `foreach(array_keys($_POST) as $key){$value=$_POST[$key];` is more simply `foreach ($_POST as $key => $value) {`, but it is a little concerning that there is no validation or sanitization. – mickmackusa May 01 '22 at 09:26
  • `if(preg_match('/_/',$key)){$key1=preg_replace('/\_/',' ',$key); $substitute=1;} else{ $substitute=0;}` is more simply `$key1=preg_replace('/_/',' ',$key, -1, $substitute)` – mickmackusa May 01 '22 at 09:28
  • thanks for the brevity tips :-) The sanitization happens Perlside... though I am no security expert i do not know if this exposes me before it reaches the Perl... any ideas r.e. the main issue gratefully received. – Beeblbrox May 01 '22 at 09:34
  • You can avoid instantiating `$data[$key]=array();` and `$data[$key1]=array();` if you replace the `array_push()` calls with square brace push syntax. e.g. `$data[$key1][] = $entry;` – mickmackusa May 01 '22 at 09:36
  • I do not know why `stripslashes()` is being called here. You might like to try using explicit `&` delimiters with `http_build_query()`. – mickmackusa May 01 '22 at 09:38
  • i found extraneous slashes were being imposed on certain chars i can't even begin to recall where they were coming from (this was years ago) - it wasn't me though. As for explicit ampersands I already tried manually constructing a query string which threw exactly the same problem... @mickmackusa – Beeblbrox May 01 '22 at 09:42
  • Perhaps have a read of this: https://stackoverflow.com/a/62055171/2943403 – mickmackusa May 01 '22 at 09:43
  • thanks, had a look, just seems to recommend using url_encode manually (done that no luck) or using http_build_query (which I do in the example given) - so no new info there unless I am missing something? @mickmackusa – Beeblbrox May 01 '22 at 09:54
  • `preg_match('/aspdf\=true/',$url)` can be `str_contains($url, 'aspdf=true')` or `strpos($url, 'aspdf=true') !== false`. There is no reason to rely on regex to check a static string. – mickmackusa May 01 '22 at 09:54
  • I suppose my final suggestion is [UTF-8 all the way through](https://stackoverflow.com/q/279170/2943403) – mickmackusa May 01 '22 at 09:56

0 Answers0