Skip to content

Commit be5e379

Browse files
author
Hartmut Holzgraefe
committed
HTTP_RAW_POST_DATA BC fixes
# hopefully all done, commiting anyway to continue work on my home box php://input stream fixes (POST data handerl mangles data, CLI crashbug)
1 parent ef7bd02 commit be5e379

File tree

4 files changed

+39
-23
lines changed

4 files changed

+39
-23
lines changed

ext/standard/php_fopen_wrapper.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -75,22 +75,24 @@ static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count
7575
{
7676
size_t read_bytes = 0;
7777
if(!stream->eof) {
78-
if(SG(request_info).post_data) { /* data has already been read by a post handler */
79-
read_bytes = SG(request_info).post_data_length - stream->position;
78+
if(SG(request_info).raw_post_data) { /* data has already been read by a post handler */
79+
read_bytes = SG(request_info).raw_post_data_length - stream->position;
8080
if(read_bytes <= count) {
8181
stream->eof = 1;
8282
} else {
8383
read_bytes = count;
8484
}
8585
if(read_bytes) {
86-
memcpy(buf, SG(request_info).post_data + stream->position, read_bytes);
86+
memcpy(buf, SG(request_info).raw_post_data + stream->position, read_bytes);
8787
}
88-
} else {
88+
} else if(sapi_module.read_post) {
8989
read_bytes = sapi_module.read_post(buf, count TSRMLS_CC);
9090
if(read_bytes <= 0){
9191
stream->eof = 1;
9292
read_bytes = 0;
9393
}
94+
} else {
95+
stream->eof = 1;
9496
}
9597
}
9698

@@ -133,7 +135,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch
133135

134136
if (!strcasecmp(path, "input")) {
135137
return php_stream_alloc(&php_stream_input_ops, NULL, 0, "rb");
136-
}
138+
}
137139

138140
if (!strcasecmp(path, "stdin")) {
139141
fp = fdopen(dup(STDIN_FILENO), mode);

main/SAPI.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ static void sapi_read_post_data(TSRMLS_D)
174174
post_reader_func(TSRMLS_C);
175175
}
176176

177-
if(PG(always_populate_raw_post_data) && sapi_module.default_post_reader) {
177+
if(sapi_module.default_post_reader) {
178178
sapi_module.default_post_reader(TSRMLS_C);
179179
}
180180
}
@@ -294,6 +294,7 @@ SAPI_API void sapi_activate(TSRMLS_D)
294294
SG(headers_sent) = 0;
295295
SG(read_post_bytes) = 0;
296296
SG(request_info).post_data = NULL;
297+
SG(request_info).raw_post_data = NULL;
297298
SG(request_info).current_user = NULL;
298299
SG(request_info).current_user_length = 0;
299300
SG(request_info).no_headers = 0;
@@ -355,13 +356,16 @@ SAPI_API void sapi_deactivate(TSRMLS_D)
355356
efree(SG(request_info).post_data);
356357
} else if (SG(server_context)) {
357358
if(sapi_module.read_post) {
358-
// make sure we've consumed all request input data
359+
/* make sure we've consumed all request input data */
359360
char dummy[SAPI_POST_BLOCK_SIZE];
360361
while(sapi_module.read_post(dummy, sizeof(dummy)-1 TSRMLS_CC) > 0) {
361362
/* empty loop body */
362363
}
363364
}
364365
}
366+
if (SG(request_info).raw_post_data) {
367+
efree(SG(request_info).raw_post_data);
368+
}
365369
if (SG(request_info).auth_user) {
366370
efree(SG(request_info).auth_user);
367371
}

main/SAPI.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,10 @@ extern SAPI_API sapi_module_struct sapi_module; /* true global */
7171
typedef struct {
7272
const char *request_method;
7373
char *query_string;
74-
char *post_data;
74+
char *post_data, *raw_post_data;
7575
char *cookie_data;
7676
long content_length;
77-
uint post_data_length;
77+
uint post_data_length, raw_post_data_length;
7878

7979
char *path_translated;
8080
char *request_uri;

main/php_content_types.c

+24-14
Original file line numberDiff line numberDiff line change
@@ -38,25 +38,35 @@ static sapi_post_entry php_post_entries[] = {
3838
SAPI_API SAPI_POST_READER_FUNC(php_default_post_reader)
3939
{
4040
char *data = NULL;
41+
int length = 0;
4142

42-
if(PG(always_populate_raw_post_data)) {
43-
if(NULL == SG(request_info).post_data) { /* no data yet */
44-
if(NULL == SG(request_info).post_entry) {
45-
/* no post handler registered, so we just swallow the data */
46-
sapi_read_standard_form_data(TSRMLS_C);
47-
data = SG(request_info).post_data;
48-
SG(request_info).post_data = NULL;
49-
SG(request_info).post_data_length = 0;
50-
}
51-
} else {
52-
/* copy existing post data */
53-
data = estrndup(SG(request_info).post_data, SG(request_info).post_data_length);
43+
// $HTTP_RAW_POST_DATA registration
44+
if(!strcmp(SG(request_info).request_method, "POST")) {
45+
if(NULL == SG(request_info).post_entry) {
46+
/* no post handler registered, so we just swallow the data */
47+
sapi_read_standard_form_data(TSRMLS_C);
48+
length = SG(request_info).post_data_length;
49+
data = estrndup(SG(request_info).post_data, length);
50+
} else if(PG(always_populate_raw_post_data) && SG(request_info).post_data) {
51+
length = SG(request_info).post_data_length;
52+
data = estrndup(SG(request_info).post_data, length);
5453
}
55-
5654
if(data) {
57-
SET_VAR_STRINGL("HTTP_RAW_POST_DATA", data, SG(request_info).post_data_length);
55+
SET_VAR_STRINGL("HTTP_RAW_POST_DATA", data, length);
5856
}
5957
}
58+
59+
/* for php://input stream:
60+
some post handlers modify the content of request_info.post_data
61+
so for now we need a copy for the php://input stream
62+
in the long run post handlers should be changed to not touch
63+
request_info.post_data for memory preservation reasons
64+
*/
65+
if(SG(request_info).post_data) {
66+
SG(request_info).raw_post_data = estrndup(SG(request_info).post_data, SG(request_info).post_data_length);
67+
SG(request_info).raw_post_data_length = SG(request_info).post_data_length;
68+
}
69+
6070
}
6171
/* }}} */
6272

0 commit comments

Comments
 (0)