php / php/php-src

FFI struct with flexible array member

Offen
#7,949 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Extension: ffi Status: Verified
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

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

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie damit, den bereitgestellten PHP 8.1.1 CLI-Reproduzierer auszuführen und das gemeldete Verhalten von FFI flexiblen Array-Mitgliedern zu untersuchen, einschließlich der Grenzfehler und fehlgeschlagenen Zuweisungen. Ermitteln Sie die vorgesehene unterstützte Vorgehensweise zur Verwendung eines flexiblen Array-Mitglieds und überprüfen Sie, dass sich der Reproduzierer entsprechend dieser Erwartung konsistent verhält.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
c, php
Bereich
backend
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.