ます’s Blog - どうでもいい記事100選

どうでもいい記事100選

Refine fix for multibyte char hanling inside command names and args(続き)

先日のですが。
(改めて)よく見てみたら、mblen関数が「0」か「1」の値を返さない限り文字はSKIP(削除)されちゃうんですね。またしてもミスリードか。。。最近多くてスミマセン。_| ̄|○
どっちにしてもネグられちゃうって事なのかしら。。。とほほ。
主戦場であるSolarisで確認してみたところ、意外な結果に。

% cd /usr/local/src
% cat ./exec.php
<?php

  declare( encoding="EUC-JP" );

  var_dump( PHP_VERSION );

  var_dump( escapeshellcmd( "/usr/local/src/あ" ) );
  var_dump( escapeshellarg( "/usr/local/src/あ" ) );

  var_dump( escapeshellcmd( "'/usr/local/src/あ'" ) );
  var_dump( escapeshellarg( "'/usr/local/src/あ'" ) );

  var_dump( escapeshellcmd( '"/usr/local/src/あ"' ) );
  var_dump( escapeshellarg( '"/usr/local/src/あ"' ) );

  var_dump( escapeshellcmd( "/usr/local/あ/src" ) );
  var_dump( escapeshellarg( "/usr/local/あ/src" ) );

  var_dump( escapeshellcmd( "'/usr/local/あ/src'" ) );
  var_dump( escapeshellarg( "'/usr/local/あ/src'" ) );

  var_dump( escapeshellcmd( '"/usr/local/あ/src"' ) );
  var_dump( escapeshellarg( '"/usr/local/あ/src"' ) );

?>

% ./php-5.2.6-dev-cli-200803250130 ./exec.php
string(12) "5.2.6RC3-dev"
string(17) "/usr/local/src/あ"
string(19) "'/usr/local/src/あ'"
string(19) "'/usr/local/src/あ'"
string(27) "''\''/usr/local/src/あ'\'''"
string(19) ""/usr/local/src/あ""
string(21) "'"/usr/local/src/あ"'"
string(17) "/usr/local/あ/src"
string(19) "'/usr/local/あ/src'"
string(19) "'/usr/local/あ/src'"
string(27) "''\''/usr/local/あ/src'\'''"
string(19) ""/usr/local/あ/src""
string(21) "'"/usr/local/あ/src"'"

% uname -a
SunOS 5.10 Generic_127111-05 sun4v sparc SUNW,Sun-Fire-T200 Solaris

うぉっ!ネグられてない。何で?
PHPの該当ソース(/php-src/ext/standard/exec.c)っぽくなるような、ちょっとしたプログラムを作って動作の確認。

% cd /usr/local/src
% cat ./mblen.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main( void )
{
   char *target = "あAいBうCえDおE";
   int x, y, size;

   size = strlen( target );

   fprintf( stdout, "[DBG]:----------------------------------\n" );
   fprintf( stdout, "[DBG]: size  = %d\n", size );

   for( x = 0; x < size; ++x )
   {
      y = mblen( ( target + x ), ( size - x ) );

      fprintf( stdout, "[DBG]:----------------------------------\n" );
      fprintf( stdout, "[DBG]: now   = %d\n", x );
      fprintf( stdout, "[DBG]: mblen = %d\n", y );

      if( y > 1 )
        {
           x += ( y - 1 );
        }
   }

   return 0;
}

% gcc -Wall -o ./mblen ./mblen.c
% ./mblen
[DBG]:----------------------------------
[DBG]: size  = 15
[DBG]:----------------------------------
[DBG]: now   = 0
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 1
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 2
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 3
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 4
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 5
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 6
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 7
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 8
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 9
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 10
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 11
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 12
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 13
[DBG]: mblen = 1
[DBG]:----------------------------------
[DBG]: now   = 14
[DBG]: mblen = 1

% locale
LANG=ja_JP.eucJP
LC_CTYPE="ja_JP.eucJP"
LC_NUMERIC="ja_JP.eucJP"
LC_TIME="ja_JP.eucJP"
LC_COLLATE="ja_JP.eucJP"
LC_MONETARY="ja_JP.eucJP"
LC_MESSAGES="ja_JP.eucJP"
LC_ALL=ja_JP.eucJP

全部「1」が返ってきてるし。。。この結果は正しいのか?_| ̄|○
Linuxで似たようなプログラムを実行してみるとマルチバイトの部分は「-1」だったりと、Solarisとは全然違った結果に(文字コードUTF-8にしても結果は同じでした)。
それにしても、この差は気になるな。。。余計に混乱してきた。うーん。段々と深みにハマってきている感じがする。
環境変数「LANG」と環境変数「LC_ALL」しか設定してないけど、localeの設定が正しくないのかしら。