Archived

This forum has been archived. Please start a new discussion on GitHub.

IcePHP fails to use php.ini variables correctly (PHP CLI)

Hello,

after upgrading from Ice 3.3.0 to 3.4.1 I realized that the php.ini configuration mechanism changed, but whatever I tried, I couldn't get our systems up and running.

The example code used to demonstrate the problem is:
[PHP]
<?php
require 'Ice.php';

$initData = new Ice_InitializationData;
$initData->properties = Ice_getProperties();
$ICE = Ice_initialize($initData);

$ICE->stringToProxy("test:ssl -h 127.0.0.1 -p 10000");
print("OK\n");
?>
[/PHP]

The ice config entry is:
ice.config=/etc/ice.config

And /etc/ice.config contains:
Ice.Plugin.IceSSL=IceSSL:createIceSSL

Execution of this fails:
[dev ~/test]$ php t.php
PHP Fatal error:  Uncaught exception ::Ice::EndpointParseException
{
    str = invalid endpoint `ssl -h 127.0.0.1 -p 10000' in `test:ssl -h 127.0.0.1 -p 10000'
}
  thrown in /tmp/t.php on line 8

So I checked the ini values (<?php print_r(ini_get_all()); ?>) and realized that the identifiers had been mangled to 8 bytes max (this is on a 64bit platform):
    [ice.con] => Array
        (
            [global_value] => ^@basic_
            [local_value] => ^@basic_
            [access] => 4
        )

    [ice.hid] => Array
        (
            [global_value] => 1^@Ice v
            [local_value] => 1^@Ice v
            [access] => 4
        )

    [ice.opt] => Array
        (
            [global_value] => ^@basic_
            [local_value] => ^@basic_
            [access] => 4
        )

    [ice.pro] => Array
        (
            [global_value] => ^@basic_
            [local_value] => ^@basic_
            [access] => 4
        )

I checked the plugin source and found const_cast<char*>(string literal) lines in the code. I removed those, which basically results in the following patch:
--- /tmp/Init.cpp       2010-12-03 02:35:20.000000000 +0000
+++ Init.cpp    2010-12-03 02:37:09.000000000 +0000
@@ -58,10 +58,10 @@
 // Declare initialization file entries.
 //
 PHP_INI_BEGIN()
-  PHP_INI_ENTRY(const_cast<char*>("ice.config"), const_cast<char*>(""), PHP_INI_SYSTEM, 0)
-  PHP_INI_ENTRY(const_cast<char*>("ice.options"), const_cast<char*>(""), PHP_INI_SYSTEM, 0)
-  PHP_INI_ENTRY(const_cast<char*>("ice.profiles"), const_cast<char*>(""), PHP_INI_SYSTEM, 0)
-  PHP_INI_ENTRY(const_cast<char*>("ice.hide_profiles"), const_cast<char*>("1"), PHP_INI_SYSTEM, 0)
+  PHP_INI_ENTRY("ice.config", "", PHP_INI_SYSTEM, 0)
+  PHP_INI_ENTRY("ice.options", "", PHP_INI_SYSTEM, 0)
+  PHP_INI_ENTRY("ice.profiles", "", PHP_INI_SYSTEM, 0)
+  PHP_INI_ENTRY("ice.hide_profiles", "1", PHP_INI_SYSTEM, 0)
 PHP_INI_END()
 
 extern "C"

Now the output of ini_get_all changed to:
    [ice.config] => Array
        (
            [global_value] => /etc/ice.config
            [local_value] => /etc/ice.config
            [access] => 4
        )

    [ice.hide_profiles] => Array
        (
            [global_value] => 1
            [local_value] => 1
            [access] => 4
        )

    [ice.options] => Array
        (
            [global_value] => 
            [local_value] => 
            [access] => 4
        )

    [ice.profiles] => Array
        (
            [global_value] => 
            [local_value] => 
            [access] => 4
        )

Much better, but unfortunately execution still failed as above.

Checking Communicator.cpp I stumbled over two more const_casts of char* using the INI_STR macro. I corrected those as well, as seen in this patch:
--- /tmp/Communicator.cpp       2010-12-03 02:38:04.000000000 +0000
+++ Communicator.cpp    2010-12-03 02:39:25.000000000 +0000
@@ -1322,12 +1322,12 @@
     // Create the profiles from configuration settings.
     //
     const char* empty = "";
-    const char* config = INI_STR(const_cast<char*>("ice.config"));
+    const char* config = INI_STR("ice.config");
     if(!config)
     {
         config = empty;
     }
-    const char* options = INI_STR(const_cast<char*>("ice.options"));
+    const char* options = INI_STR("ice.options");
     if(!options)
     {
         options = empty;
@@ -1337,7 +1337,7 @@
         return false;
     }
 
-    const char* profiles = INI_STR(const_cast<char*>("ice.profiles"));
+    const char* profiles = INI_STR("ice.profiles");
     if(!profiles)
     {
         profiles = empty;
@@ -1349,7 +1349,7 @@
             return false;
         }
 
-        if(INI_BOOL(const_cast<char*>("ice.hide_profiles")))
+        if(INI_BOOL("ice.hide_profiles"))
         {
             memset(const_cast<char*>(profiles), '*', strlen(profiles));
             //

After this change, the code executes as expected:
[dev ~/test]$ php t.php
OK

Platform is FreeBSD 7.x and 8.x amd64
Gcc 4.2.1
Ice 3.4.1

Even so this is on FreeBSD I'm convinced that this problem isn't limited to the platform, I've seen various outputs showing that on the net, as e.g. in
http://www.zeroc.com/forums/help-center/5096-ice-php.html#post22331

Not certain if there are more const_cast problems in the code - there are comments wondering about ini_get_all crashing in it which might be related - and removing them adds some deprecated warnings - but still much better than having it not work at all.

Cheers
Michael

Comments

  • mes
    mes California
    Thanks for the bug report. We recently discovered these issues ourselves. Needless to say, they'll be fixed in the next release.

    Regards,
    Mark
  • Hi Mark,

    thanks for your quick response, good to hear that this will be fixed soon. Is there any "known issues" section on your webpage I might have missed? Would be great time saver.

    cheers
    Michael