php / php/php-src

sscanf c conversion specifier

オープン
#19,088 コメント 11 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Bug Extension: standard Status: Verified
主要言語
C
スター
40.4k
フォーク
8.2k
平均マージ
2日 13時間
マージ済み PR(30日)
96

説明

Description

The following code:

<?php

$r = sscanf('     ', '%c%n', $c, $n)
and var_dump(compact('r', 'c', 'n'));

Resulted in this output:

array(3) {
  'r' =>
  int(2)
  'c' =>
  string(0) ""
  'n' =>
  int(0)
}

But I expected this output instead:

array(3) {
  'r' =>
  int(2)
  'c' =>
  string(1) " "
  'n' =>
  int(1)
}

Expectation by fscanf, scanf, sscanf - convert formatted input, cf. Revision of IEEE Std 1003.1-2008, via Open Group Base Specifications Issue 7, 2018 edition, specifically "[CX] The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of POSIX.1-2017 defers to the ISO C standard", quoting:

The following conversion specifiers are valid:

[...]

  • c
    • Matches a sequence of bytes of the number specified by the field width (1 if no field width is present in the conversion specification). No null byte is added. The normal skip over white-space characters shall be suppressed in this case.

For PHP versions older of that date, please refer to the equally older documentation for these dates.

Why is the expectation important?

The c conversion specifier is important to scan over white space characters, so that it adjoins the s conversion specifier (supported by PHP sscanf(), compare https://github.com/php/php-src/issues/11201#issuecomment-1537369396 ) and/or leaving a space character in the $format string (supported by PHP sscanf()).


https://3v4l.org/9E2d1

8.4.10

https://3v4l.org/9E2d1	9E2d1

1:	<?php
2:	
3:	$r = sscanf('     ', '%c%n', $c, $n)
4:	and var_dump(compact('r', 'c', 'n'));
5:	
output [versions: 8.4.10 | released 2025-07-03 | took 29 ms, 18.55 MiB]
	O: array(3) {
	O:   ["r"]=>
	O:   int(2)
	O:   ["c"]=>
	O:   string(0) ""
	O:   ["n"]=>
	O:   int(0)
	O: }

+eol:

https://3v4l.org/9E2d1	9E2d1

1:	<?php
2:	
3:	$r = sscanf('     ', '%c%n', $c, $n)
4:	and var_dump(compact('r', 'c', 'n'));
5:	
output [versions: 4.3.2 - 4.3.11, 4.4.0 - 4.4.9, 5.0.0 - 5.0.5, 5.1.0 - 5.1.6, 5.2.0 - 5.2.17, 5.3.0 - 5.3.29, 5.4.0 - 5.4.45, 5.5.0 - 5.5.38, 5.6.0 - 5.6.40, 7.0.4 - 7.0.33, 7.1.0 - 7.1.33, 7.2.0 - 7.2.34, 7.3.0 - 7.3.33, 7.4.0 - 7.4.33, 8.0.0 - 8.0.30, 8.1.0 - 8.1.33, 8.2.0 - 8.2.29, 8.3.0 - 8.3.23, 8.4.1 - 8.4.10]
	O: array(3) {
	O:   ["r"]=>
	O:   int(2)
	O:   ["c"]=>
	O:   string(0) ""
	O:   ["n"]=>
	O:   int(0)
	O: }
output [versions: 7.0.0 - 7.0.3]
	O: array(3) {
	O:   ["r"]=>
	O:   int(2)
	O:   ["c"]=>
	O:   &string(0) ""
	O:   ["n"]=>
	O:   &int(0)
	O: }
output [versions: 4.3.0 - 4.3.1]
	O: array(3) {
	O:   ["r"]=>
	O:   int(2)
	O:   ["c"]=>
	O:   string(0) ""
	O:   ["n"]=>
	O:   string(0) ""
	O: }
PHP Version
PHP 8.4.10 (cli) (built: Jul  3 2025 12:41:53) (NTS)
Copyright (c) The PHP Group
Built by Debian
Zend Engine v4.4.10, Copyright (c) Zend Technologies
    with Zend OPcache v8.4.10, Copyright (c), by Zend Technologies
    with Xdebug v3.4.4, Copyright (c) 2002-2025, by Derick Rethans
Operating System

No response

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

提供されている sscanf('%c%n') の再現例から始め、PHP の sscanf の実装と変換指定子に関する既存のテストを見つけてください。%c の動作を引用されている POSIX/ISO C の要件と比較し、その後、期待される空白の扱いを示す回帰テストカバレッジを追加して、報告された出力を確認してください。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
c, php
領域
backend
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
おおむね明確
初心者へのやさしさ
48/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。