php / php/php-src

FFI struct with flexible array member

Aperta
#7,949 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

Bug Extension: ffi Status: Verified
Lingua principale
C
Stelle
40.4k
Fork
8.1k
Merge medio
2g 13h
PR unite (30g)
96

Descrizione

Description

The following code:

<?php

echo 'Creating FFI struct...' . PHP_EOL;
$value = FFI::new('struct {
    int32_t length;
    char data[]; 
}');

echo 'Our struct is:' . PHP_EOL;
var_dump($value);
echo 'Our struct->data is:' . PHP_EOL;
var_dump($value->data);

echo 'Please keep in memory following will not work:' . PHP_EOL;
try {
    $value->data = FFI::new('char[4]');
} catch (Throwable $t) {
    echo '    - ' . $t->getMessage() . PHP_EOL;
}

echo PHP_EOL . 'Let\'s try something dirty:' . PHP_EOL;
var_dump($value->data[0]); // Well, it's ok, FFI is unsafe
var_dump($value->data[1000]); // No problem at all, we should carefully check boundaries 

echo PHP_EOL . 'And even more dirtier:' . PHP_EOL;
$value->data[0] = 'a';
var_dump($value);
var_dump($value->data[0]);
echo 'I think I could broke something.' . PHP_EOL;

echo PHP_EOL . 'Let\'s fill our struct with value: ' . PHP_EOL;
FFI::memcpy($value, pack('V', 5), 4);
var_dump($value);

echo PHP_EOL . 'Will it work for array member? ' . PHP_EOL;
try {
    FFI::memcpy($value, pack('V', 5) . 'aaaa', 8);
    var_dump($value);
} catch (Throwable $t) {
    echo '    - ' . $t->getMessage() . PHP_EOL;
    echo 'Seems like it won\'t.' . PHP_EOL;
}

echo PHP_EOL . 'Maybe I can assign data directly to array member? ' . PHP_EOL;
try {
    FFI::memcpy($value->data, 'aaaa', 4);
    var_dump($value);
} catch (Throwable $t) {
    echo '    - ' . $t->getMessage() . PHP_EOL;
    echo 'Doesn\'t work either.' . PHP_EOL;
}

echo PHP_EOL . 'Or maybe I can assign to array member itself? ' . PHP_EOL;
try {
    $value->data = FFI::new('char[4]');
    var_dump($value);
} catch (Throwable) {
    echo '    - ' . $t->getMessage() . PHP_EOL;
}
echo 'Do you remember last time we did this we got different error: ' . PHP_EOL;
echo '    - It was "Incompatible types when assigning to type \'char[]\' from type \'char[4]\'"' . PHP_EOL;

Resulted in this output:

Creating FFI struct...
Our struct is:
object(FFI\CData:struct <anonymous>)#1 (2) {
  ["length"]=>
  int(0)
  ["data"]=>
  object(FFI\CData:char[])#2 (0) {
  }
}
Our struct->data is:
object(FFI\CData:char[])#2 (0) {
}
Please keep in memory following will not work:
    - Incompatible types when assigning to type 'char[]' from type 'char[4]'

Let's try something dirty:
string(1) "▒"
string(1) "▒"

And even more dirtier:
object(FFI\CData:struct <anonymous>)#1 (2) {
  ["length"]=>
  int(0)
  ["data"]=>
  object(FFI\CData:char[])#2 (0) {
  }
}
string(1) "a"
I think I could broke something.

Let's fill our struct with value:
object(FFI\CData:struct <anonymous>)#1 (2) {
  ["length"]=>
  int(5)
  ["data"]=>
  object(FFI\CData:char[])#2 (0) {
  }
}

Will it work for array member?
    - Attempt to write over data boundary
Seems like it won't.

Maybe I can assign data directly to array member?
    - Attempt to write over data boundary
Doesn't work either.

Or maybe I can assign to array member itself?
    - Attempt to write over data boundary
Do you remember last time we did this we got different error, it was:
    - Incompatible types when assigning to type 'char[]' from type 'char[4]'

I did not expect something different, but it seems strange to me - flexible array members in structs are allowed, but I can't find the way how to use them.

PHP Version

PHP 8.1.1 (cli) NTS

Operating System

No response

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Iniziare eseguendo il riproduttore CLI PHP 8.1.1 fornito e analizzando il comportamento segnalato dei membri di array flessibili di FFI, inclusi gli errori ai limiti e i fallimenti delle assegnazioni. Determinare il modo supportato previsto per utilizzare un membro di array flessibile e verificare che il riproduttore si comporti in modo coerente con tale aspettativa.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c, php
Ambito
backend
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.