1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.0 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_0.txt. |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Ilia Alshanetsky <ilia@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22 #include "php.h"
23
24 #include <magic.h>
25 /*
26 * HOWMANY specifies the maximum offset libmagic will look at
27 * this is currently hardcoded in the libmagic source but not exported
28 */
29 #ifndef HOWMANY
30 #define HOWMANY 65536
31 #endif
32
33 #include "php_ini.h"
34 #include "ext/standard/info.h"
35 #include "ext/standard/file.h" /* needed for context stuff */
36 #include "php_fileinfo.h"
37 #include "fopen_wrappers.h" /* needed for is_url */
38 #include "Zend/zend_exceptions.h"
39
40 /* {{{ macros and type definitions */
41 typedef struct _php_fileinfo {
42 zend_long options;
43 struct magic_set *magic;
44 } php_fileinfo;
45
46 static zend_object_handlers finfo_object_handlers;
47 zend_class_entry *finfo_class_entry;
48
49 typedef struct _finfo_object {
50 php_fileinfo *ptr;
51 zend_object zo;
52 } finfo_object;
53
54 #define FILEINFO_DECLARE_INIT_OBJECT(object) \
55 zval *object = getThis();
56
php_finfo_fetch_object(zend_object * obj)57 static inline finfo_object *php_finfo_fetch_object(zend_object *obj) {
58 return (finfo_object *)((char*)(obj) - XtOffsetOf(finfo_object, zo));
59 }
60
61 #define Z_FINFO_P(zv) php_finfo_fetch_object(Z_OBJ_P((zv)))
62
63 #define FILEINFO_REGISTER_OBJECT(_object, _ptr) \
64 { \
65 finfo_object *obj; \
66 obj = Z_FINFO_P(_object); \
67 obj->ptr = _ptr; \
68 }
69
70 #define FILEINFO_FROM_OBJECT(finfo, object) \
71 { \
72 finfo_object *obj = Z_FINFO_P(object); \
73 finfo = obj->ptr; \
74 if (!finfo) { \
75 php_error_docref(NULL, E_WARNING, "The invalid fileinfo object."); \
76 RETURN_FALSE; \
77 } \
78 }
79
80 /* {{{ finfo_objects_free
81 */
finfo_objects_free(zend_object * object)82 static void finfo_objects_free(zend_object *object)
83 {
84 finfo_object *intern = php_finfo_fetch_object(object);
85
86 if (intern->ptr) {
87 magic_close(intern->ptr->magic);
88 efree(intern->ptr);
89 }
90
91 zend_object_std_dtor(&intern->zo);
92 }
93 /* }}} */
94
95 /* {{{ finfo_objects_new
96 */
finfo_objects_new(zend_class_entry * class_type)97 PHP_FILEINFO_API zend_object *finfo_objects_new(zend_class_entry *class_type)
98 {
99 finfo_object *intern;
100
101 intern = zend_object_alloc(sizeof(finfo_object), class_type);
102
103 zend_object_std_init(&intern->zo, class_type);
104 object_properties_init(&intern->zo, class_type);
105 intern->zo.handlers = &finfo_object_handlers;
106
107 return &intern->zo;
108 }
109 /* }}} */
110
111 /* {{{ arginfo */
112 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_open, 0, 0, 0)
113 ZEND_ARG_INFO(0, options)
114 ZEND_ARG_INFO(0, arg)
115 ZEND_END_ARG_INFO()
116
117 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_close, 0, 0, 1)
118 ZEND_ARG_INFO(0, finfo)
119 ZEND_END_ARG_INFO()
120
121 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_set_flags, 0, 0, 2)
122 ZEND_ARG_INFO(0, finfo)
123 ZEND_ARG_INFO(0, options)
124 ZEND_END_ARG_INFO()
125
126 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_set_flags, 0, 0, 1)
127 ZEND_ARG_INFO(0, options)
128 ZEND_END_ARG_INFO()
129
130 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_file, 0, 0, 2)
131 ZEND_ARG_INFO(0, finfo)
132 ZEND_ARG_INFO(0, filename)
133 ZEND_ARG_INFO(0, options)
134 ZEND_ARG_INFO(0, context)
135 ZEND_END_ARG_INFO()
136
137 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_file, 0, 0, 1)
138 ZEND_ARG_INFO(0, filename)
139 ZEND_ARG_INFO(0, options)
140 ZEND_ARG_INFO(0, context)
141 ZEND_END_ARG_INFO()
142
143 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_buffer, 0, 0, 2)
144 ZEND_ARG_INFO(0, finfo)
145 ZEND_ARG_INFO(0, string)
146 ZEND_ARG_INFO(0, options)
147 ZEND_ARG_INFO(0, context)
148 ZEND_END_ARG_INFO()
149
150 ZEND_BEGIN_ARG_INFO_EX(arginfo_finfo_method_buffer, 0, 0, 1)
151 ZEND_ARG_INFO(0, string)
152 ZEND_ARG_INFO(0, options)
153 ZEND_ARG_INFO(0, context)
154 ZEND_END_ARG_INFO()
155
156 ZEND_BEGIN_ARG_INFO_EX(arginfo_mime_content_type, 0, 0, 1)
157 ZEND_ARG_INFO(0, string)
158 ZEND_END_ARG_INFO()
159 /* }}} */
160
161 /* {{{ finfo_class_functions
162 */
163 static const zend_function_entry finfo_class_functions[] = {
164 ZEND_ME_MAPPING(finfo, finfo_open, arginfo_finfo_open, ZEND_ACC_PUBLIC)
165 ZEND_ME_MAPPING(set_flags, finfo_set_flags,arginfo_finfo_method_set_flags, ZEND_ACC_PUBLIC)
166 ZEND_ME_MAPPING(file, finfo_file, arginfo_finfo_method_file, ZEND_ACC_PUBLIC)
167 ZEND_ME_MAPPING(buffer, finfo_buffer, arginfo_finfo_method_buffer, ZEND_ACC_PUBLIC)
168 PHP_FE_END
169 };
170 /* }}} */
171
172 #define FINFO_SET_OPTION(magic, options) \
173 if (magic_setflags(magic, options) == -1) { \
174 php_error_docref(NULL, E_WARNING, "Failed to set option '" ZEND_LONG_FMT "' %d:%s", \
175 options, magic_errno(magic), magic_error(magic)); \
176 RETURN_FALSE; \
177 }
178
179 /* True global resources - no need for thread safety here */
180 static int le_fileinfo;
181 /* }}} */
182
finfo_resource_destructor(zend_resource * rsrc)183 void finfo_resource_destructor(zend_resource *rsrc) /* {{{ */
184 {
185 if (rsrc->ptr) {
186 php_fileinfo *finfo = (php_fileinfo *) rsrc->ptr;
187 magic_close(finfo->magic);
188 efree(rsrc->ptr);
189 rsrc->ptr = NULL;
190 }
191 }
192 /* }}} */
193
194
195 /* {{{ fileinfo_functions[]
196 */
197 static const zend_function_entry fileinfo_functions[] = {
198 PHP_FE(finfo_open, arginfo_finfo_open)
199 PHP_FE(finfo_close, arginfo_finfo_close)
200 PHP_FE(finfo_set_flags, arginfo_finfo_set_flags)
201 PHP_FE(finfo_file, arginfo_finfo_file)
202 PHP_FE(finfo_buffer, arginfo_finfo_buffer)
203 PHP_FE(mime_content_type, arginfo_mime_content_type)
204 PHP_FE_END
205 };
206 /* }}} */
207
208 /* {{{ PHP_MINIT_FUNCTION
209 */
PHP_MINIT_FUNCTION(finfo)210 PHP_MINIT_FUNCTION(finfo)
211 {
212 zend_class_entry _finfo_class_entry;
213 INIT_CLASS_ENTRY(_finfo_class_entry, "finfo", finfo_class_functions);
214 _finfo_class_entry.create_object = finfo_objects_new;
215 finfo_class_entry = zend_register_internal_class(&_finfo_class_entry);
216
217 /* copy the standard object handlers to you handler table */
218 memcpy(&finfo_object_handlers, &std_object_handlers, sizeof(zend_object_handlers));
219 finfo_object_handlers.offset = XtOffsetOf(finfo_object, zo);
220 finfo_object_handlers.free_obj = finfo_objects_free;
221 finfo_object_handlers.clone_obj = NULL;
222
223 le_fileinfo = zend_register_list_destructors_ex(finfo_resource_destructor, NULL, "file_info", module_number);
224
225 REGISTER_LONG_CONSTANT("FILEINFO_NONE", MAGIC_NONE, CONST_CS|CONST_PERSISTENT);
226 REGISTER_LONG_CONSTANT("FILEINFO_SYMLINK", MAGIC_SYMLINK, CONST_CS|CONST_PERSISTENT);
227 REGISTER_LONG_CONSTANT("FILEINFO_MIME", MAGIC_MIME, CONST_CS|CONST_PERSISTENT);
228 REGISTER_LONG_CONSTANT("FILEINFO_MIME_TYPE", MAGIC_MIME_TYPE, CONST_CS|CONST_PERSISTENT);
229 REGISTER_LONG_CONSTANT("FILEINFO_MIME_ENCODING",MAGIC_MIME_ENCODING, CONST_CS|CONST_PERSISTENT);
230 /* REGISTER_LONG_CONSTANT("FILEINFO_COMPRESS", MAGIC_COMPRESS, CONST_CS|CONST_PERSISTENT); disabled, as it does fork now */
231 REGISTER_LONG_CONSTANT("FILEINFO_DEVICES", MAGIC_DEVICES, CONST_CS|CONST_PERSISTENT);
232 REGISTER_LONG_CONSTANT("FILEINFO_CONTINUE", MAGIC_CONTINUE, CONST_CS|CONST_PERSISTENT);
233 #ifdef MAGIC_PRESERVE_ATIME
234 REGISTER_LONG_CONSTANT("FILEINFO_PRESERVE_ATIME", MAGIC_PRESERVE_ATIME, CONST_CS|CONST_PERSISTENT);
235 #endif
236 #ifdef MAGIC_RAW
237 REGISTER_LONG_CONSTANT("FILEINFO_RAW", MAGIC_RAW, CONST_CS|CONST_PERSISTENT);
238 #endif
239 #if 0
240 /* seems not usable yet. */
241 REGISTER_LONG_CONSTANT("FILEINFO_APPLE", MAGIC_APPLE, CONST_CS|CONST_PERSISTENT);
242 #endif
243 REGISTER_LONG_CONSTANT("FILEINFO_EXTENSION", MAGIC_EXTENSION, CONST_CS|CONST_PERSISTENT);
244
245 return SUCCESS;
246 }
247 /* }}} */
248
249 /* {{{ fileinfo_module_entry
250 */
251 zend_module_entry fileinfo_module_entry = {
252 STANDARD_MODULE_HEADER,
253 "fileinfo",
254 fileinfo_functions,
255 PHP_MINIT(finfo),
256 NULL,
257 NULL,
258 NULL,
259 PHP_MINFO(fileinfo),
260 PHP_FILEINFO_VERSION,
261 STANDARD_MODULE_PROPERTIES
262 };
263 /* }}} */
264
265 #ifdef COMPILE_DL_FILEINFO
266 ZEND_GET_MODULE(fileinfo)
267 #endif
268
269 /* {{{ PHP_MINFO_FUNCTION
270 */
PHP_MINFO_FUNCTION(fileinfo)271 PHP_MINFO_FUNCTION(fileinfo)
272 {
273 char magic_ver[5];
274
275 (void)snprintf(magic_ver, 4, "%d", magic_version());
276 magic_ver[4] = '\0';
277
278 php_info_print_table_start();
279 php_info_print_table_row(2, "fileinfo support", "enabled");
280 php_info_print_table_row(2, "libmagic", magic_ver);
281 php_info_print_table_end();
282 }
283 /* }}} */
284
285 /* {{{ proto resource finfo_open([int options [, string arg]])
286 Create a new fileinfo resource. */
PHP_FUNCTION(finfo_open)287 PHP_FUNCTION(finfo_open)
288 {
289 zend_long options = MAGIC_NONE;
290 char *file = NULL;
291 size_t file_len = 0;
292 php_fileinfo *finfo;
293 FILEINFO_DECLARE_INIT_OBJECT(object)
294 char resolved_path[MAXPATHLEN];
295 zend_error_handling zeh;
296 int flags = object ? ZEND_PARSE_PARAMS_THROW : 0;
297
298 if (zend_parse_parameters_ex(flags, ZEND_NUM_ARGS(), "|lp", &options, &file, &file_len) == FAILURE) {
299 RETURN_FALSE;
300 }
301
302 if (object) {
303 finfo_object *finfo_obj = Z_FINFO_P(object);
304
305 zend_replace_error_handling(EH_THROW, NULL, &zeh);
306
307 if (finfo_obj->ptr) {
308 magic_close(finfo_obj->ptr->magic);
309 efree(finfo_obj->ptr);
310 finfo_obj->ptr = NULL;
311 }
312 }
313
314 if (file_len == 0) {
315 file = NULL;
316 } else if (file && *file) { /* user specified file, perform open_basedir checks */
317
318 if (php_check_open_basedir(file)) {
319 if (object) {
320 zend_restore_error_handling(&zeh);
321 if (!EG(exception)) {
322 zend_throw_exception(NULL, "Constructor failed", 0);
323 }
324 }
325 RETURN_FALSE;
326 }
327 if (!expand_filepath_with_mode(file, resolved_path, NULL, 0, CWD_EXPAND)) {
328 if (object) {
329 zend_restore_error_handling(&zeh);
330 if (!EG(exception)) {
331 zend_throw_exception(NULL, "Constructor failed", 0);
332 }
333 }
334 RETURN_FALSE;
335 }
336 file = resolved_path;
337 }
338
339 finfo = emalloc(sizeof(php_fileinfo));
340
341 finfo->options = options;
342 finfo->magic = magic_open(options);
343
344 if (finfo->magic == NULL) {
345 efree(finfo);
346 php_error_docref(NULL, E_WARNING, "Invalid mode '" ZEND_LONG_FMT "'.", options);
347 if (object) {
348 zend_restore_error_handling(&zeh);
349 if (!EG(exception)) {
350 zend_throw_exception(NULL, "Constructor failed", 0);
351 }
352 }
353 RETURN_FALSE;
354 }
355
356 if (magic_load(finfo->magic, file) == -1) {
357 php_error_docref(NULL, E_WARNING, "Failed to load magic database at '%s'.", file);
358 magic_close(finfo->magic);
359 efree(finfo);
360 if (object) {
361 zend_restore_error_handling(&zeh);
362 if (!EG(exception)) {
363 zend_throw_exception(NULL, "Constructor failed", 0);
364 }
365 }
366 RETURN_FALSE;
367 }
368
369 if (object) {
370 zend_restore_error_handling(&zeh);
371 FILEINFO_REGISTER_OBJECT(object, finfo);
372 } else {
373 RETURN_RES(zend_register_resource(finfo, le_fileinfo));
374 }
375 }
376 /* }}} */
377
378 /* {{{ proto resource finfo_close(resource finfo)
379 Close fileinfo resource. */
PHP_FUNCTION(finfo_close)380 PHP_FUNCTION(finfo_close)
381 {
382 php_fileinfo *finfo;
383 zval *zfinfo;
384
385 if (zend_parse_parameters(ZEND_NUM_ARGS(), "r", &zfinfo) == FAILURE) {
386 RETURN_FALSE;
387 }
388
389 if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) {
390 RETURN_FALSE;
391 }
392
393 zend_list_close(Z_RES_P(zfinfo));
394
395 RETURN_TRUE;
396 }
397 /* }}} */
398
399 /* {{{ proto bool finfo_set_flags(resource finfo, int options)
400 Set libmagic configuration options. */
PHP_FUNCTION(finfo_set_flags)401 PHP_FUNCTION(finfo_set_flags)
402 {
403 zend_long options;
404 php_fileinfo *finfo;
405 zval *zfinfo;
406 FILEINFO_DECLARE_INIT_OBJECT(object)
407
408 if (object) {
409 if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &options) == FAILURE) {
410 RETURN_FALSE;
411 }
412 FILEINFO_FROM_OBJECT(finfo, object);
413 } else {
414 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rl", &zfinfo, &options) == FAILURE) {
415 RETURN_FALSE;
416 }
417 if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) {
418 RETURN_FALSE;
419 }
420 }
421
422 FINFO_SET_OPTION(finfo->magic, options)
423 finfo->options = options;
424
425 RETURN_TRUE;
426 }
427 /* }}} */
428
429 #define FILEINFO_MODE_BUFFER 0
430 #define FILEINFO_MODE_STREAM 1
431 #define FILEINFO_MODE_FILE 2
432
_php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS,int mode,int mimetype_emu)433 static void _php_finfo_get_type(INTERNAL_FUNCTION_PARAMETERS, int mode, int mimetype_emu) /* {{{ */
434 {
435 zend_long options = 0;
436 char *ret_val = NULL, *buffer = NULL;
437 size_t buffer_len;
438 php_fileinfo *finfo = NULL;
439 zval *zfinfo, *zcontext = NULL;
440 zval *what;
441 char mime_directory[] = "directory";
442
443 struct magic_set *magic = NULL;
444 FILEINFO_DECLARE_INIT_OBJECT(object)
445
446 if (mimetype_emu) {
447
448 /* mime_content_type(..) emulation */
449 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &what) == FAILURE) {
450 return;
451 }
452
453 switch (Z_TYPE_P(what)) {
454 case IS_STRING:
455 buffer = Z_STRVAL_P(what);
456 buffer_len = Z_STRLEN_P(what);
457 mode = FILEINFO_MODE_FILE;
458 break;
459
460 case IS_RESOURCE:
461 mode = FILEINFO_MODE_STREAM;
462 break;
463
464 default:
465 php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments");
466 RETURN_FALSE;
467 }
468
469 magic = magic_open(MAGIC_MIME_TYPE);
470 if (magic_load(magic, NULL) == -1) {
471 php_error_docref(NULL, E_WARNING, "Failed to load magic database.");
472 goto common;
473 }
474 } else if (object) {
475 if (zend_parse_parameters(ZEND_NUM_ARGS(), "s|lr", &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
476 RETURN_FALSE;
477 }
478 FILEINFO_FROM_OBJECT(finfo, object);
479 magic = finfo->magic;
480 } else {
481 if (zend_parse_parameters(ZEND_NUM_ARGS(), "rs|lr", &zfinfo, &buffer, &buffer_len, &options, &zcontext) == FAILURE) {
482 RETURN_FALSE;
483 }
484 if ((finfo = (php_fileinfo *)zend_fetch_resource(Z_RES_P(zfinfo), "file_info", le_fileinfo)) == NULL) {
485 RETURN_FALSE;
486 }
487 magic = finfo->magic;
488 }
489
490 /* Set options for the current file/buffer. */
491 if (options) {
492 FINFO_SET_OPTION(magic, options)
493 }
494
495 switch (mode) {
496 case FILEINFO_MODE_BUFFER:
497 {
498 ret_val = (char *) magic_buffer(magic, buffer, buffer_len);
499 break;
500 }
501
502 case FILEINFO_MODE_STREAM:
503 {
504 php_stream *stream;
505 zend_off_t streampos;
506
507 php_stream_from_zval_no_verify(stream, what);
508 if (!stream) {
509 goto common;
510 }
511
512 streampos = php_stream_tell(stream); /* remember stream position for restoration */
513 php_stream_seek(stream, 0, SEEK_SET);
514
515 ret_val = (char *) magic_stream(magic, stream);
516
517 php_stream_seek(stream, streampos, SEEK_SET);
518 break;
519 }
520
521 case FILEINFO_MODE_FILE:
522 {
523 /* determine if the file is a local file or remote URL */
524 const char *tmp2;
525 php_stream_wrapper *wrap;
526 php_stream_statbuf ssb;
527
528 if (buffer == NULL || !*buffer) {
529 php_error_docref(NULL, E_WARNING, "Empty filename or path");
530 RETVAL_FALSE;
531 goto clean;
532 }
533 if (CHECK_NULL_PATH(buffer, buffer_len)) {
534 php_error_docref(NULL, E_WARNING, "Invalid path");
535 RETVAL_FALSE;
536 goto clean;
537 }
538
539 wrap = php_stream_locate_url_wrapper(buffer, &tmp2, 0);
540
541 if (wrap) {
542 php_stream *stream;
543 php_stream_context *context = php_stream_context_from_zval(zcontext, 0);
544
545 #ifdef PHP_WIN32
546 if (php_stream_stat_path_ex(buffer, 0, &ssb, context) == SUCCESS) {
547 if (ssb.sb.st_mode & S_IFDIR) {
548 ret_val = mime_directory;
549 goto common;
550 }
551 }
552 #endif
553
554 stream = php_stream_open_wrapper_ex(buffer, "rb", REPORT_ERRORS, NULL, context);
555
556 if (!stream) {
557 RETVAL_FALSE;
558 goto clean;
559 }
560
561 if (php_stream_stat(stream, &ssb) == SUCCESS) {
562 if (ssb.sb.st_mode & S_IFDIR) {
563 ret_val = mime_directory;
564 } else {
565 ret_val = (char *)magic_stream(magic, stream);
566 }
567 }
568
569 php_stream_close(stream);
570 }
571 break;
572 }
573
574 default:
575 php_error_docref(NULL, E_WARNING, "Can only process string or stream arguments");
576 }
577
578 common:
579 if (ret_val) {
580 RETVAL_STRING(ret_val);
581 } else {
582 php_error_docref(NULL, E_WARNING, "Failed identify data %d:%s", magic_errno(magic), magic_error(magic));
583 RETVAL_FALSE;
584 }
585
586 clean:
587 if (mimetype_emu) {
588 magic_close(magic);
589 }
590
591 /* Restore options */
592 if (options) {
593 FINFO_SET_OPTION(magic, finfo->options)
594 }
595 return;
596 }
597 /* }}} */
598
599 /* {{{ proto string finfo_file(resource finfo, char *file_name [, int options [, resource context]])
600 Return information about a file. */
PHP_FUNCTION(finfo_file)601 PHP_FUNCTION(finfo_file)
602 {
603 _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_FILE, 0);
604 }
605 /* }}} */
606
607 /* {{{ proto string finfo_buffer(resource finfo, char *string [, int options [, resource context]])
608 Return information about a string buffer. */
PHP_FUNCTION(finfo_buffer)609 PHP_FUNCTION(finfo_buffer)
610 {
611 _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, FILEINFO_MODE_BUFFER, 0);
612 }
613 /* }}} */
614
615 /* {{{ proto string mime_content_type(string filename|resource stream)
616 Return content-type for file */
PHP_FUNCTION(mime_content_type)617 PHP_FUNCTION(mime_content_type)
618 {
619 _php_finfo_get_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, -1, 1);
620 }
621 /* }}} */
622