php_vm 1.3.10 → 1.3.11

Sign up to get free protection for your applications and to get access to all the features.
@@ -73,6 +73,13 @@ static void php_vm_exception_hook(zval *ex TSRMLS_DC)
73
73
  EG(exception) = NULL;
74
74
  }
75
75
 
76
+ static void php_vm_reset_status(TSRMLS_D)
77
+ {
78
+ EG(exit_status) = 0;
79
+ EG(exception) = NULL;
80
+ rb_cv_set(rb_mPHPVM, "@@last_error_reporting", Qnil);
81
+ }
82
+
76
83
 
77
84
  // PHP
78
85
 
@@ -81,12 +88,16 @@ VALUE php_eval_string(char *code, int code_len, int use_retval TSRMLS_DC)
81
88
  int syntax_error = 0;
82
89
  zval retval;
83
90
 
91
+ // reset
92
+ php_vm_reset_status(TSRMLS_C);
93
+
84
94
  // eval
85
95
  zend_try {
86
96
  if (zend_eval_stringl(code, code_len, (use_retval ? &retval : NULL), "php_vm" TSRMLS_CC)==FAILURE) {
87
97
  syntax_error = 1;
88
98
  }
89
99
  } zend_end_try();
100
+ EG(active_op_array) = NULL;
90
101
 
91
102
  // syntax error
92
103
  if (syntax_error) {
@@ -363,6 +374,9 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
363
374
  {
364
375
  int result = FAILURE;
365
376
 
377
+ // reset
378
+ php_vm_reset_status(TSRMLS_C);
379
+
366
380
  // call info
367
381
  zend_fcall_info fci;
368
382
  zend_fcall_info_cache fcc;
@@ -421,6 +435,7 @@ int call_php_method(zend_class_entry *ce, zval *obj, zend_function *mptr, int ar
421
435
  // release
422
436
  zend_fcall_info_args_clear(&fci, 1);
423
437
  zval_ptr_dtor(&z_args);
438
+ EG(active_op_array) = NULL;
424
439
 
425
440
  // result
426
441
  if (g_exception || rb_cv_get(rb_mPHPVM, "@@last_error_reporting")!=Qnil) {
@@ -834,6 +849,7 @@ VALUE define_global_classes()
834
849
  while (SUCCESS == zend_hash_get_current_data_ex(ht, (void **)&z_classname, &pos)) {
835
850
  char *classname = Z_STRVAL_P(*z_classname);
836
851
  int classname_len = Z_STRLEN_P(*z_classname);
852
+
837
853
  if (0x41<=classname[0] && classname[0]<=0x5a) {
838
854
  // define class as const if class name is uppercase
839
855
  if (!rb_const_defined(rb_mPHPGlobal, rb_intern(classname))) {
@@ -844,6 +860,7 @@ VALUE define_global_classes()
844
860
  // define class as module function if class name is lowercase
845
861
  rb_define_module_function(rb_mPHPGlobal, classname, rb_php_global_class_call, 0);
846
862
  }
863
+
847
864
  zend_hash_move_forward_ex(ht, &pos);
848
865
  }
849
866
  zval_ptr_dtor(&z_val);
@@ -1467,7 +1484,7 @@ void Init_php_vm()
1467
1484
  rb_define_singleton_method(rb_mPHPVM, "get_class", rb_php_vm_get_class, 1);
1468
1485
  rb_define_singleton_method(rb_mPHPVM, "define_global", rb_php_vm_define_global, 0);
1469
1486
 
1470
- rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.10"));
1487
+ rb_define_const(rb_mPHPVM, "VERSION", rb_str_new2("1.3.11"));
1471
1488
 
1472
1489
  rb_cv_set(rb_mPHPVM, "@@output_handler", Qnil);
1473
1490
  rb_cv_set(rb_mPHPVM, "@@error_handler", Qnil);
@@ -82,8 +82,15 @@ static VALUE zval_to_value_object(zval *z)
82
82
  const char *name = "";
83
83
  zend_uint name_len = 0;
84
84
  int dup;
85
+
86
+ // get class name
85
87
  dup = zend_get_object_classname(z, &name, &name_len TSRMLS_CC);
88
+ if (dup!=SUCCESS) {
89
+ rb_raise(rb_ePHPError, "did not get class name from zend_class_entry");
90
+ }
91
+
86
92
  VALUE v_name = rb_str_new(name, name_len);
93
+ efree((char*)name);
87
94
 
88
95
  // class
89
96
  VALUE class = rb_php_class_get(rb_cPHPClass, v_name);
@@ -0,0 +1 @@
1
+ <?php
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/ruby
2
+
3
+ require 'test/unit'
4
+
5
+ test_dir = File.dirname(__FILE__)
6
+ exit Test::Unit::AutoRunner.run(true, test_dir)
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_output_handler_accessor
14
+ hooked_output = nil
15
+ pr = Proc.new {|output|
16
+ hooked_output = output
17
+ }
18
+
19
+ # proc object
20
+ PHPVM.output_handler = pr
21
+ assert_equal(pr, PHPVM.output_handler)
22
+
23
+ # hook
24
+ PHPVM.exec("echo 'HelloWorld';")
25
+ assert_equal("HelloWorld", hooked_output)
26
+
27
+ # nil object
28
+ PHPVM.output_handler = nil
29
+ assert_nil(PHPVM.output_handler)
30
+ end
31
+
32
+ def test_error_handler_accessor
33
+ hooked_error_reporting = nil
34
+ pr = Proc.new {|error_reporting|
35
+ hooked_error_reporting = error_reporting
36
+ }
37
+
38
+ # proc object
39
+ PHPVM.error_handler = pr
40
+ assert_equal(pr, PHPVM.error_handler)
41
+
42
+ # hook
43
+ PHPVM.exec("strpos();")
44
+ assert_instance_of(PHPVM::PHPErrorReporting, hooked_error_reporting)
45
+
46
+ # nil object
47
+ PHPVM.error_handler = nil
48
+ assert_nil(PHPVM.error_handler)
49
+ end
50
+
51
+ def test_require
52
+ # exists php file
53
+ filepath = File.expand_path(__FILE__+"/../require.php")
54
+ assert_equal(true, PHPVM.require(filepath))
55
+
56
+ # non exists php file
57
+ assert_raises(PHPVM::PHPErrorReporting) {
58
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
59
+ PHPVM.require(filepath)
60
+ }
61
+ end
62
+
63
+ def test_require_once
64
+ # exists php file
65
+ filepath = File.expand_path(__FILE__+"/../require.php")
66
+ assert_equal(true, PHPVM.require_once(filepath))
67
+
68
+ # non exists php file
69
+ assert_raises(PHPVM::PHPErrorReporting) {
70
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
71
+ PHPVM.require_once(filepath)
72
+ }
73
+ end
74
+
75
+ def test_include
76
+ # exists php file
77
+ filepath = File.expand_path(__FILE__+"/../require.php")
78
+ assert_equal(true, PHPVM.include(filepath))
79
+
80
+ # non exists php file
81
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
82
+ assert_equal(false, PHPVM.include(filepath))
83
+ end
84
+
85
+ def test_include_once
86
+ # exists php file
87
+ filepath = File.expand_path(__FILE__+"/../require.php")
88
+ assert_equal(true, PHPVM.include_once(filepath))
89
+
90
+ # non exists php file
91
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
92
+ assert_equal(false, PHPVM.include_once(filepath))
93
+ end
94
+
95
+ def test_get_class
96
+ # exists php class
97
+ assert_instance_of(PHPVM::PHPClass, PHPVM.get_class("SimpleXMLElement"))
98
+ assert_equal(PHPVM::PHPClass.get("SimpleXMLElement"), PHPVM.get_class("SimpleXMLElement"))
99
+
100
+ # non exists php class
101
+ assert_raises(PHPVM::PHPError) {
102
+ PHPVM.get_class("NonExistsClass")
103
+ }
104
+ end
105
+
106
+ def test_define_global
107
+ assert_equal(true, PHPVM.define_global)
108
+ end
109
+
110
+ def test_version
111
+ assert_match(/^\d+\.\d+\.\d+$/, PHPVM::VERSION)
112
+ end
113
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPClass < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_get
14
+ # exists php class
15
+ assert_instance_of(PHPVM::PHPClass, PHPVM::PHPClass.get("SimpleXMLElement"))
16
+
17
+ # non exists php class
18
+ assert_raises(PHPVM::PHPError) {
19
+ PHPVM.get_class("NonExistsClass")
20
+ }
21
+ end
22
+
23
+ def test_new
24
+ # normal object
25
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
26
+ xml = phpSimpleXMLElement.new("<root><item>Hello World!!</item></root>")
27
+ assert_instance_of(PHPVM::PHPObject, xml)
28
+
29
+ # exception object
30
+ phpException = PHPVM.get_class("Exception")
31
+ exc = phpException.new("php error")
32
+ assert_instance_of(PHPVM::PHPExceptionObject, exc)
33
+ end
34
+
35
+ def test_name
36
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
37
+ assert_equal("SimpleXMLElement", phpSimpleXMLElement.name)
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPErrorReporting < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ PHPVM.error_handler = nil
12
+ end
13
+
14
+ def test_raise_exception
15
+ assert_raises(PHPVM::PHPErrorReporting) {
16
+ PHPVM.exec("trigger_error('fatal err', E_USER_ERROR);")
17
+ }
18
+
19
+ assert_raises(PHPVM::PHPErrorReporting) {
20
+ PHPVM::PHPGlobal.trigger_error("fatal err", PHPVM::PHPGlobal::E_USER_ERROR)
21
+ }
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPExceptionObject < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_raise_exception
14
+ assert_raises(PHPVM::PHPExceptionObject) {
15
+ PHPVM.exec("throw new Exception('error');")
16
+ }
17
+ end
18
+ end
@@ -0,0 +1,111 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPGlobal < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_require
14
+ # exists php file
15
+ filepath = File.expand_path(__FILE__+"/../require.php")
16
+ assert_equal(true, PHPVM::PHPGlobal.require(filepath))
17
+
18
+ # exists ruby file
19
+ # return false if require already imported file.
20
+ filepath = "rubygems"
21
+ assert_equal(false, PHPVM::PHPGlobal.require(filepath))
22
+
23
+ # non exists file
24
+ assert_raises(LoadError) {
25
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
26
+ PHPVM::PHPGlobal.require(filepath)
27
+ }
28
+ end
29
+
30
+ def test_require_once
31
+ # exists php file
32
+ filepath = File.expand_path(__FILE__+"/../require.php")
33
+ assert_equal(true, PHPVM::PHPGlobal.require_once(filepath))
34
+
35
+ # exists ruby file
36
+ # return false if require already imported file.
37
+ filepath = "rubygems"
38
+ assert_equal(false, PHPVM::PHPGlobal.require(filepath))
39
+
40
+ # non exists file
41
+ assert_raises(LoadError) {
42
+ filepath = File.expand_path(__FILE__+"/../non_exists_file.php")
43
+ PHPVM::PHPGlobal.require_once(filepath)
44
+ }
45
+ end
46
+
47
+ def test_echo
48
+ hooked_output = nil
49
+ PHPVM.output_handler = Proc.new{|output|
50
+ hooked_output = output
51
+ }
52
+
53
+ # string
54
+ PHPVM::PHPGlobal.echo("abcdefg")
55
+ assert_equal("abcdefg", hooked_output)
56
+
57
+ # array
58
+ PHPVM::PHPGlobal.echo([])
59
+ assert_equal("Array", hooked_output)
60
+ end
61
+
62
+ def test_print
63
+ hooked_output = nil
64
+ PHPVM.output_handler = Proc.new{|output|
65
+ hooked_output = output
66
+ }
67
+
68
+ # string
69
+ PHPVM::PHPGlobal.print("abcdefg")
70
+ assert_equal("abcdefg", hooked_output)
71
+
72
+ # array
73
+ PHPVM::PHPGlobal.print([])
74
+ assert_equal("Array", hooked_output)
75
+ end
76
+
77
+ def test_array
78
+ assert_equal([], PHPVM::PHPGlobal.array())
79
+ assert_equal([1, 2, 3], PHPVM::PHPGlobal.array(1, 2, 3))
80
+ assert_equal({"aaa"=>"bbb"}, PHPVM::PHPGlobal.array("aaa"=>"bbb"))
81
+ end
82
+
83
+ def test_native_function
84
+ # http_build_query
85
+ assert_equal("aaa=bbb", PHPVM::PHPGlobal.http_build_query({"aaa"=>"bbb"}))
86
+
87
+ # preg_replace
88
+ assert_equal("aBcdef", PHPVM::PHPGlobal.preg_replace('/b/', "B", "abcdef"))
89
+
90
+ # number_format
91
+ assert_equal("123,456,789", PHPVM::PHPGlobal.number_format(123456789))
92
+ end
93
+
94
+ def test_native_class
95
+ # stdClass
96
+ assert_instance_of(PHPVM::PHPClass, PHPVM::PHPGlobal::stdClass)
97
+ assert_equal(PHPVM::PHPClass.get("stdClass"), PHPVM::PHPGlobal::stdClass)
98
+
99
+ # SimpleXMLElement
100
+ assert_instance_of(PHPVM::PHPClass, PHPVM::PHPGlobal::SimpleXMLElement)
101
+ assert_equal(PHPVM::PHPClass.get("SimpleXMLElement"), PHPVM::PHPGlobal::SimpleXMLElement)
102
+
103
+ xml = PHPVM::PHPGlobal::SimpleXMLElement.new("<root><item>Hello World!!</item></root>")
104
+ assert_equal("Hello World!!", xml.item.to_s)
105
+ end
106
+
107
+ def test_native_constant
108
+ # PHP_VERSION
109
+ assert_match(/^\d+\.\d+\.\d+$/, PHPVM::PHPGlobal::PHP_VERSION)
110
+ end
111
+ end
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPObject < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+
12
+ # define MagicAccessor
13
+ begin
14
+ PHPVM.get_class("MagicAccessor")
15
+ rescue => e
16
+ PHPVM.exec <<-EOS
17
+ class MagicAccessor
18
+ {
19
+ protected $_data = array();
20
+
21
+ public function __get($name)
22
+ {
23
+ return isset($this->_data[$name]) ? $this->_data[$name] : null;
24
+ }
25
+
26
+ public function __set($name, $val)
27
+ {
28
+ $this->_data[$name] = $val;
29
+ }
30
+ }
31
+ EOS
32
+ end
33
+
34
+ # define MagicCaller
35
+ begin
36
+ PHPVM.get_class("MagicCaller")
37
+ rescue => e
38
+ PHPVM.exec <<-EOS
39
+ class MagicCaller
40
+ {
41
+ public function __call($name, $args)
42
+ {
43
+ return $name." ".implode(", ", $args);
44
+ }
45
+ }
46
+ EOS
47
+ end
48
+ end
49
+
50
+ def test_php_class
51
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
52
+ xml = phpSimpleXMLElement.new("<root><item>Hello World!!</item></root>")
53
+
54
+ assert_equal(phpSimpleXMLElement, xml.php_class)
55
+ end
56
+
57
+ def test_call
58
+ phpException = PHPVM.get_class("Exception")
59
+ exc = phpException.new("exc message", 123)
60
+
61
+ assert_equal("exc message", exc.getMessage)
62
+ assert_equal(123, exc.getCode)
63
+ end
64
+
65
+ def test_magic_access
66
+ # default object handler
67
+ phpMagicAccessor = PHPVM.get_class("MagicAccessor")
68
+ acc = phpMagicAccessor.new
69
+ acc.aaa = "AAA"
70
+
71
+ assert_equal("AAA", acc.aaa)
72
+ assert_nil(acc.bbb)
73
+
74
+ # custom object handler
75
+ phpSimpleXMLElement = PHPVM.get_class("SimpleXMLElement")
76
+ xml = phpSimpleXMLElement.new("<root><item>Hello World!!</item></root>")
77
+
78
+ assert_equal("Hello World!!", xml.item.to_s)
79
+ end
80
+
81
+ def test_magic_call
82
+ phpMagicCaller = PHPVM.get_class("MagicCaller")
83
+ cal = phpMagicCaller.new
84
+
85
+ assert_equal("hello aaa, bbb, ccc", cal.hello("aaa", "bbb", "ccc"))
86
+ end
87
+ end
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/ruby
2
+
3
+ $LOAD_PATH << File.expand_path(__FILE__+"/../../ext/php_vm")
4
+ require "test/unit"
5
+ require "php_vm"
6
+
7
+ class TC_PHPVM_PHPSyntaxError < Test::Unit::TestCase
8
+ def setup
9
+ PHPVM.output_handler = Proc.new{|output| }
10
+ PHPVM.error_handler = Proc.new{|error_reporting| }
11
+ end
12
+
13
+ def test_raise_exception
14
+ assert_raises(PHPVM::PHPSyntaxError) {
15
+ PHPVM.exec("invalid syntax code")
16
+ }
17
+ end
18
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: php_vm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.10
4
+ version: 1.3.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-01-08 00:00:00.000000000 Z
12
+ date: 2013-01-09 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: php_vm is a native bridge between Ruby and PHP.
15
15
  email:
@@ -31,6 +31,15 @@ files:
31
31
  - ext/php_vm/php_vm_z2v.c
32
32
  - ext/php_vm/php_vm_z2v.h
33
33
  - php_vm.gemspec
34
+ - test/require.php
35
+ - test/run_test.rb
36
+ - test/test_php_vm.rb
37
+ - test/test_php_vm_php_class.rb
38
+ - test/test_php_vm_php_error_reporting.rb
39
+ - test/test_php_vm_php_exception_object.rb
40
+ - test/test_php_vm_php_global.rb
41
+ - test/test_php_vm_php_object.rb
42
+ - test/test_php_vm_php_syntax_error.rb
34
43
  homepage: https://github.com/yoshida-eth0/ruby-php_vm
35
44
  licenses: []
36
45
  post_install_message:
@@ -55,4 +64,13 @@ rubygems_version: 1.8.23
55
64
  signing_key:
56
65
  specification_version: 3
57
66
  summary: php_vm is a native bridge between Ruby and PHP.
58
- test_files: []
67
+ test_files:
68
+ - test/require.php
69
+ - test/run_test.rb
70
+ - test/test_php_vm.rb
71
+ - test/test_php_vm_php_class.rb
72
+ - test/test_php_vm_php_error_reporting.rb
73
+ - test/test_php_vm_php_exception_object.rb
74
+ - test/test_php_vm_php_global.rb
75
+ - test/test_php_vm_php_object.rb
76
+ - test/test_php_vm_php_syntax_error.rb