Skip to content

Commit bc53dd3

Browse files
committed
Ensure argv is passed through properly
1 parent e36a618 commit bc53dd3

File tree

4 files changed

+49
-11
lines changed

4 files changed

+49
-11
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ console.log(response.body.toString())
5858
### `new Php(config)`
5959

6060
* `config` {Object} Configuration object
61+
* `argv` {String[]} Process arguments. **Default:** []
6162
* `docroot` {String} Document root for PHP. **Default:** process.cwd()
6263
* Returns: {Php}
6364

@@ -67,6 +68,7 @@ Construct a new PHP instance to which to dispatch requests.
6768
import { Php } from '@platformatic/php-node'
6869

6970
const php = new Php({
71+
argv: process.argv,
7072
docroot: process.cwd()
7173
})
7274
````

__test__/handler.spec.mjs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,11 @@ test('Support input/output streams', async (t) => {
1515
t.teardown(() => mockroot.clean())
1616

1717
const php = new Php({
18-
argv: process.argv,
1918
docroot: mockroot.path
2019
})
2120

2221
const req = new Request({
23-
method: 'GET',
22+
method: 'POST',
2423
url: 'http://example.com/index.php',
2524
body: Buffer.from('Hello, from Node.js!')
2625
})
@@ -39,12 +38,10 @@ test('Capture logs', async (t) => {
3938
t.teardown(() => mockroot.clean())
4039

4140
const php = new Php({
42-
argv: process.argv,
4341
docroot: mockroot.path
4442
})
4543

4644
const req = new Request({
47-
method: 'GET',
4845
url: 'http://example.com/index.php'
4946
})
5047

@@ -62,12 +59,10 @@ test('Capture exceptions', async (t) => {
6259
t.teardown(() => mockroot.clean())
6360

6461
const php = new Php({
65-
argv: process.argv,
6662
docroot: mockroot.path
6763
})
6864

6965
const req = new Request({
70-
method: 'GET',
7166
url: 'http://example.com/index.php'
7267
})
7368

@@ -89,12 +84,10 @@ test('Support request and response headers', async (t) => {
8984
t.teardown(() => mockroot.clean())
9085

9186
const php = new Php({
92-
argv: process.argv,
9387
docroot: mockroot.path
9488
})
9589

9690
const req = new Request({
97-
method: 'GET',
9891
url: 'http://example.com/index.php',
9992
headers: {
10093
'X-Test': ['Hello, from Node.js!']
@@ -106,3 +99,33 @@ test('Support request and response headers', async (t) => {
10699
t.is(res.body.toString(), 'Hello, from Node.js!')
107100
t.is(res.headers.get('X-Test'), 'Hello, from PHP!')
108101
})
102+
103+
test('Has expected args', async (t) => {
104+
const mockroot = await MockRoot.from({
105+
'index.php': `<?php
106+
echo "[";
107+
$first = true;
108+
foreach ($argv as $value) {
109+
if ($first) { $first = false; }
110+
else { echo ","; }
111+
echo "\\"$value\\"";
112+
}
113+
echo "]";
114+
?>`
115+
})
116+
t.teardown(() => mockroot.clean())
117+
118+
const php = new Php({
119+
argv: process.argv,
120+
docroot: mockroot.path
121+
})
122+
123+
const req = new Request({
124+
url: 'http://example.com/index.php'
125+
})
126+
127+
const res = await php.handleRequest(req)
128+
t.is(res.status, 200)
129+
130+
t.is(res.body.toString('utf8'), JSON.stringify(process.argv))
131+
})

crates/php/src/embed.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::{
22
env::Args,
3-
ffi::c_char,
3+
ffi::{c_char, CString},
44
path::{Path, PathBuf},
55
sync::Arc,
66
};
@@ -189,6 +189,15 @@ impl Handler for Embed {
189189
.unwrap_or(0);
190190
let cookie_data = nullable_cstr(headers.get("Cookie"))?;
191191

192+
let argc = self.args.len() as i32;
193+
let mut argv_ptrs = vec![];
194+
for arg in self.args.iter() {
195+
let string = CString::new(arg.as_bytes()).map_err(|_| {
196+
EmbedException::CStringEncodeFailed(arg.to_owned())
197+
})?;
198+
argv_ptrs.push(string.into_raw());
199+
}
200+
192201
// Prepare memory stream of the code
193202
let mut file_handle = unsafe {
194203
let mut file_handle = zend_file_handle {
@@ -221,8 +230,8 @@ impl Handler for Embed {
221230

222231
// Reset state
223232
globals.request_info.proto_num = 110;
224-
globals.request_info.argc = 0;
225-
globals.request_info.argv = std::ptr::null_mut();
233+
globals.request_info.argc = argc;
234+
globals.request_info.argv = argv_ptrs.as_mut_ptr();
226235
globals.request_info.headers_read = false;
227236
globals.sapi_headers.http_response_code = 200;
228237

crates/php/src/sapi.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ pub extern "C" fn sapi_module_deactivate() -> c_int {
201201
{
202202
let mut globals = SapiGlobals::get_mut();
203203

204+
for i in 0..globals.request_info.argc {
205+
drop_str(unsafe { *globals.request_info.argv.offset(i as isize) });
206+
}
207+
204208
globals.server_context = std::ptr::null_mut();
205209
globals.request_info.argc = 0;
206210
globals.request_info.argv = std::ptr::null_mut();

0 commit comments

Comments
 (0)