mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Make syslog() binary safe
Closes GH-7245 Co-authored-by: Nikita Popov <nikita.ppv@googlemail.com>
This commit is contained in:
parent
fae7cec6fb
commit
0ba155cd57
6 changed files with 87 additions and 45 deletions
|
@ -471,6 +471,9 @@ PHP 8.1 UPGRADE NOTES
|
||||||
accessible through reflection.
|
accessible through reflection.
|
||||||
RFC: https://wiki.php.net/rfc/make-reflection-setaccessible-no-op
|
RFC: https://wiki.php.net/rfc/make-reflection-setaccessible-no-op
|
||||||
|
|
||||||
|
- Standard:
|
||||||
|
. syslog() is now binary safe.
|
||||||
|
|
||||||
========================================
|
========================================
|
||||||
6. New Functions
|
6. New Functions
|
||||||
========================================
|
========================================
|
||||||
|
|
|
@ -174,15 +174,14 @@ PHP_FUNCTION(closelog)
|
||||||
PHP_FUNCTION(syslog)
|
PHP_FUNCTION(syslog)
|
||||||
{
|
{
|
||||||
zend_long priority;
|
zend_long priority;
|
||||||
char *message;
|
zend_string *message;
|
||||||
size_t message_len;
|
|
||||||
|
|
||||||
ZEND_PARSE_PARAMETERS_START(2, 2)
|
ZEND_PARSE_PARAMETERS_START(2, 2)
|
||||||
Z_PARAM_LONG(priority)
|
Z_PARAM_LONG(priority)
|
||||||
Z_PARAM_STRING(message, message_len)
|
Z_PARAM_STR(message)
|
||||||
ZEND_PARSE_PARAMETERS_END();
|
ZEND_PARSE_PARAMETERS_END();
|
||||||
|
|
||||||
php_syslog(priority, "%s", message);
|
php_syslog_str(priority, message);
|
||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
19
ext/standard/tests/network/syslog_new_line.phpt
Normal file
19
ext/standard/tests/network/syslog_new_line.phpt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
--TEST--
|
||||||
|
Test syslog() function : new line in message
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(substr(PHP_OS, 0, 3) == "WIN")
|
||||||
|
die("skip Won't run on Windows");
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$priority = LOG_WARNING;
|
||||||
|
$message = "First line\nSecond line";
|
||||||
|
|
||||||
|
openlog('PHPT', LOG_PERROR, LOG_USER);
|
||||||
|
syslog($priority, $message);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
%SPHPT%S%r(:|-)%r First line
|
||||||
|
%SPHPT%S%r(:|-)%r Second line
|
18
ext/standard/tests/network/syslog_null_byte.phpt
Normal file
18
ext/standard/tests/network/syslog_null_byte.phpt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
--TEST--
|
||||||
|
Test syslog() function : nul byte in message
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if(substr(PHP_OS, 0, 3) == "WIN")
|
||||||
|
die("skip Won't run on Windows");
|
||||||
|
?>
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
$priority = LOG_WARNING;
|
||||||
|
$message = "A simple \0 message";
|
||||||
|
|
||||||
|
openlog('PHPT', LOG_PERROR, LOG_USER);
|
||||||
|
syslog($priority, $message);
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
%SPHPT%S%r(:|-)%r A simple \x00 message
|
|
@ -32,6 +32,45 @@
|
||||||
#define syslog std_syslog
|
#define syslog std_syslog
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
PHPAPI void php_syslog_str(int priority, const zend_string* message)
|
||||||
|
{
|
||||||
|
smart_string sbuf = {0};
|
||||||
|
|
||||||
|
if (PG(syslog_filter) == PHP_SYSLOG_FILTER_RAW) {
|
||||||
|
/* Just send it directly to the syslog */
|
||||||
|
syslog(priority, "%s", ZSTR_VAL(message));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We use < because we don't want the final NUL byte to be converted to '\x00' */
|
||||||
|
for (size_t i = 0; i < ZSTR_LEN(message); ++i) {
|
||||||
|
unsigned char c = ZSTR_VAL(message)[i];
|
||||||
|
|
||||||
|
/* check for NVT ASCII only unless test disabled */
|
||||||
|
if (((0x20 <= c) && (c <= 0x7e))) {
|
||||||
|
smart_string_appendc(&sbuf, c);
|
||||||
|
} else if ((c >= 0x80) && (PG(syslog_filter) != PHP_SYSLOG_FILTER_ASCII)) {
|
||||||
|
smart_string_appendc(&sbuf, c);
|
||||||
|
} else if (c == '\n') {
|
||||||
|
/* Smart string is not NUL terminated */
|
||||||
|
syslog(priority, "%.*s", (int)sbuf.len, sbuf.c);
|
||||||
|
smart_string_reset(&sbuf);
|
||||||
|
} else if ((c < 0x20) && (PG(syslog_filter) == PHP_SYSLOG_FILTER_ALL)) {
|
||||||
|
smart_string_appendc(&sbuf, c);
|
||||||
|
} else {
|
||||||
|
const char xdigits[] = "0123456789abcdef";
|
||||||
|
|
||||||
|
smart_string_appendl(&sbuf, "\\x", 2);
|
||||||
|
smart_string_appendc(&sbuf, xdigits[c >> 4]);
|
||||||
|
smart_string_appendc(&sbuf, xdigits[c & 0xf]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Smart string is not NUL terminated */
|
||||||
|
syslog(priority, "%.*s", (int)sbuf.len, sbuf.c);
|
||||||
|
smart_string_free(&sbuf);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef PHP_WIN32
|
#ifdef PHP_WIN32
|
||||||
PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
|
PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
|
||||||
{
|
{
|
||||||
|
@ -54,10 +93,7 @@ PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
|
||||||
#else
|
#else
|
||||||
PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
|
PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
|
||||||
{
|
{
|
||||||
const char *ptr;
|
zend_string *fbuf = NULL;
|
||||||
unsigned char c;
|
|
||||||
smart_string fbuf = {0};
|
|
||||||
smart_string sbuf = {0};
|
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -70,46 +106,12 @@ PHPAPI void php_syslog(int priority, const char *format, ...) /* {{{ */
|
||||||
}
|
}
|
||||||
|
|
||||||
va_start(args, format);
|
va_start(args, format);
|
||||||
zend_printf_to_smart_string(&fbuf, format, args);
|
fbuf = zend_vstrpprintf(0, format, args);
|
||||||
smart_string_0(&fbuf);
|
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
|
||||||
if (PG(syslog_filter) == PHP_SYSLOG_FILTER_RAW) {
|
php_syslog_str(priority, fbuf);
|
||||||
/* Just send it directly to the syslog */
|
|
||||||
syslog(priority, "%.*s", (int)fbuf.len, fbuf.c);
|
|
||||||
smart_string_free(&fbuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ptr = fbuf.c; ; ++ptr) {
|
zend_string_release(fbuf);
|
||||||
c = *ptr;
|
|
||||||
if (c == '\0') {
|
|
||||||
syslog(priority, "%.*s", (int)sbuf.len, sbuf.c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check for NVT ASCII only unless test disabled */
|
|
||||||
if (((0x20 <= c) && (c <= 0x7e)))
|
|
||||||
smart_string_appendc(&sbuf, c);
|
|
||||||
else if ((c >= 0x80) && (PG(syslog_filter) != PHP_SYSLOG_FILTER_ASCII))
|
|
||||||
smart_string_appendc(&sbuf, c);
|
|
||||||
else if (c == '\n') {
|
|
||||||
syslog(priority, "%.*s", (int)sbuf.len, sbuf.c);
|
|
||||||
smart_string_reset(&sbuf);
|
|
||||||
} else if ((c < 0x20) && (PG(syslog_filter) == PHP_SYSLOG_FILTER_ALL))
|
|
||||||
smart_string_appendc(&sbuf, c);
|
|
||||||
else {
|
|
||||||
const char xdigits[] = "0123456789abcdef";
|
|
||||||
|
|
||||||
smart_string_appendl(&sbuf, "\\x", 2);
|
|
||||||
smart_string_appendc(&sbuf, xdigits[(c / 0x10)]);
|
|
||||||
c &= 0x0f;
|
|
||||||
smart_string_appendc(&sbuf, xdigits[c]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
smart_string_free(&fbuf);
|
|
||||||
smart_string_free(&sbuf);
|
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#define PHP_SYSLOG_FILTER_RAW 3
|
#define PHP_SYSLOG_FILTER_RAW 3
|
||||||
|
|
||||||
BEGIN_EXTERN_C()
|
BEGIN_EXTERN_C()
|
||||||
|
PHPAPI void php_syslog_str(int priority, const zend_string* message);
|
||||||
PHPAPI void php_syslog(int, const char *format, ...);
|
PHPAPI void php_syslog(int, const char *format, ...);
|
||||||
PHPAPI void php_openlog(const char *, int, int);
|
PHPAPI void php_openlog(const char *, int, int);
|
||||||
END_EXTERN_C()
|
END_EXTERN_C()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue