From f85570704e3c043c505c1cb8207eb02ddb6bcf14 Mon Sep 17 00:00:00 2001 From: frost-byte Date: Sat, 8 May 2021 21:53:22 -0500 Subject: [PATCH] Add PHP8 Compatibility Fix compiler error for compile_ast Make the extension compatible with newer versions of php Convert final steps of docker build into a script Change `whitelist` to `allowed ` Make unit tests compatible with latest version of phpunit Add configuration for app engine project id Update CircleCI configuration Maintain backwards compat. for zval str dtor Make warning/notify tests backwards compatible Prevent seg fault when iterating logpoints in `ast_process` Install gcloud tools for Dockerfile using apt Remove memory leaks when creating debugger ast Update string assertions in phpunit tests Refactor Dockerfile to handle env vars needed for test build Add substitutions to cloudbuild Update php image versions used by cloudbuild Set cloud build timeout to 2100 seconds --- .circleci/config.yml | 31 + .gitignore | 3 + Dockerfile | 29 +- README.md | 8 +- build.sh | 19 + circle.yml | 19 - cloudbuild.yaml | 193 ++++-- docs/design.md | 2 +- php_stackdriver_debugger.h | 6 +- scripts/analyze_test.sh | 32 + scripts/install_test_dependencies.sh | 28 +- scripts/run_test_suite.sh | 9 +- stackdriver_debugger.c | 100 ++-- stackdriver_debugger_ast.c | 560 +++++++++--------- stackdriver_debugger_ast.h | 3 +- stackdriver_debugger_defines.h | 34 ++ stackdriver_debugger_logpoint.c | 33 +- stackdriver_debugger_logpoint.h | 1 + stackdriver_debugger_random.h | 17 +- stackdriver_debugger_snapshot.c | 15 +- stackdriver_debugger_snapshot.h | 2 + testapps/composer.json | 2 +- testapps/phpunit.xml.dist | 2 +- testapps/tests/functional/AppTest.php | 12 +- ...n_whitelist.phpt => function_allowed.phpt} | 6 +- ...set.phpt => function_allowed_ini_set.phpt} | 6 +- ...le.phpt => function_allowed_multiple.phpt} | 6 +- ....phpt => function_allowed_namespaced.phpt} | 6 +- tests/snapshots/basic_variable_dump.phpt | 4 + tests/snapshots/conditional_warning.phpt | 2 +- tests/snapshots/expressions_warning.phpt | 2 +- tests/statement_validity.phpt | 6 +- 32 files changed, 738 insertions(+), 460 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 build.sh delete mode 100644 circle.yml create mode 100755 scripts/analyze_test.sh create mode 100644 stackdriver_debugger_defines.h rename tests/{function_whitelist.phpt => function_allowed.phpt} (72%) rename tests/{function_whitelist_ini_set.phpt => function_allowed_ini_set.phpt} (68%) rename tests/{function_whitelist_multiple.phpt => function_allowed_multiple.phpt} (70%) rename tests/{function_whitelist_namespaced.phpt => function_allowed_namespaced.phpt} (76%) diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..1d10df1 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,31 @@ +# PHP CircleCI 2.0 configuration file +# +# Check https://circleci.com/docs/2.0/language-php/ for more details +# +version: 2.1 +jobs: + build: + docker: + - image: google/cloud-sdk + auth: + username: $DOCKERHUB_USER + password: $DOCKERHUB_PASSWORD + + steps: + - checkout + - run: + name: "Setup Environment" + command: | + echo 'export APPENGINE_PROJECT_ID="${APPENGINE_PROJECT_ID}"' >> $BASH_ENV + echo 'export GOOGLE_PROJECT_ID="${GOOGLE_PROJECT_ID}"' >> $BASH_ENV + echo 'export GOOGLE_COMPUTE_REGION="${GOOGLE_COMPUTE_REGION}"' >> $BASH_ENV + echo 'export GOOGLE_APPLICATION_CREDENTIALS=`echo ${GOOGLE_CREDENTIALS_BASE64} | base64 -di`' >> $BASH_ENV + apt-get update -y + apt-get -y --only-upgrade install google-cloud-sdk-kubectl-oidc google-cloud-sdk google-cloud-sdk-kpt google-cloud-sdk-cloud-build-local + gcloud --quiet config configurations create ${CLOUDSDK_ACTIVE_CONFIG_NAME} + gcloud --quiet config set project ${GOOGLE_PROJECT_ID} + echo $GOOGLE_CREDENTIALS_BASE64 | base64 -di | gcloud auth activate-service-account --key-file=- + gcloud --quiet config set compute/region ${GOOGLE_COMPUTE_REGION} + - run: + name: "Run Tests" + command: ./scripts/run_test_suite.sh diff --git a/.gitignore b/.gitignore index 3826bcc..9a6f88e 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,6 @@ tests/**/*.diff tests/**/*.sh vendor/ composer.lock +.vscode/c_cpp_properties.json +.vscode/tasks.json +.vscode/settings.json diff --git a/Dockerfile b/Dockerfile index b01c1c9..a4ecc01 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,32 +14,45 @@ ARG BASE_IMAGE FROM $BASE_IMAGE +ARG GOOGLE_CREDENTIALS_BASE64 +ARG CLOUDSDK_ACTIVE_CONFIG_NAME +ARG GOOGLE_PROJECT_ID +ARG PHP_DOCKER_GOOGLE_CREDENTIALS RUN mkdir -p /build && \ apt-get update -y && \ apt-get install -y -q --no-install-recommends \ + apt-transport-https \ build-essential \ + ca-certificates \ g++ \ gcc \ + gnupg \ libc-dev \ make \ autoconf \ curl \ git-core \ + nano \ + valgrind \ unzip +RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] http://packages.cloud.google.com/apt cloud-sdk main" | tee -a /etc/apt/sources.list.d/google-cloud-sdk.list && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - && apt-get update -y && apt-get install google-cloud-sdk -y + COPY . /build/ WORKDIR /build +RUN chmod 0755 /build/build.sh + +ENV GOOGLE_CREDENTIALS_BASE64=${GOOGLE_CREDENTIALS_BASE64:-} +ENV CLOUDSDK_ACTIVE_CONFIG_NAME=${CLOUDSDK_ACTIVE_CONFIG_NAME:-default} +ENV GOOGLE_PROJECT_ID=${GOOGLE_PROJECT_ID:-google-cloud} +ENV PHP_DOCKER_GOOGLE_CREDENTIALS=${PHP_DOCKER_GOOGLE_CREDENTIALS:-/build/gcp-creds.json} +ENV GOOGLE_APPLICATION_CREDENTIALS=${PHP_DOCKER_GOOGLE_CREDENTIALS} +RUN /build/scripts/install_test_dependencies.sh ENV TEST_PHP_ARGS="-q" \ REPORT_EXIT_STATUS=1 -RUN phpize && \ - ./configure --enable-stackdriver-debugger && \ - make clean && \ - make && \ - make test || ((find . -name '*.diff' | xargs cat) && false) && \ - make install && \ - (composer -V || scripts/install_composer.sh) && \ - scripts/run_functional_tests.sh +RUN /build/build.sh +#ENTRYPOINT [ "/bin/bash" ] diff --git a/README.md b/README.md index bd48a56..5b2e08f 100644 --- a/README.md +++ b/README.md @@ -183,22 +183,22 @@ or ini_set('stackdriver_debugger.max_time', '50'); ``` -### Whitelisting Function Calls in Conditions and Evaluated Expressions +### Allowing Function Calls in Conditions and Evaluated Expressions Setting a snapshot or logpoint should not affect the state of any application. By default, we disallow any unknown function calls that could potentially modify the state of your application. You can add additional function calls to this list by setting the ini config -`stackdriver_debugger.function_whitelist`: +`stackdriver_debugger.functions_allowed`: ``` # in php.ini -stackdriver_debugger.function_whitelist="foo,bar,MyClass::function" +stackdriver_debugger.functions_allowed="foo,bar,MyClass::function" ``` ```php -ini_set('stackdriver_debugger.function_whitelist', 'foo,bar,MyClass::function'); +ini_set('stackdriver_debugger.functions_allowed', 'foo,bar,MyClass::function'); ``` Note that all function names specified here must be declared with their full diff --git a/build.sh b/build.sh new file mode 100644 index 0000000..c2accc9 --- /dev/null +++ b/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash +set -ex + +if [ -z "${BUILD_DIR}" ]; then + BUILD_DIR='/build' +fi + +export BUILD_DIR +export BUILD_LOG_DIR='/build/log' +mkdir -p ${BUILD_DIR} ${BUILD_LOG_DIR} + +phpize && \ +./configure --enable-stackdriver-debugger && \ +make clean && \ +make && \ +make test || ((find . -name '*.diff' | xargs cat) && false) && \ +make install && \ +(composer -V || scripts/install_composer.sh) && \ +scripts/run_functional_tests.sh \ No newline at end of file diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 9296470..0000000 --- a/circle.yml +++ /dev/null @@ -1,19 +0,0 @@ -machine: - timezone: America/Los_Angeles - environment: - GCLOUD_DIR: ${HOME}/gcloud - PATH: ${GCLOUD_DIR}/google-cloud-sdk/bin:${PATH} - CLOUDSDK_CORE_DISABLE_PROMPTS: 1 - CLOUDSDK_ACTIVE_CONFIG_NAME: opencensus-php - TEST_BUILD_DIR: ${HOME} - PHP_DOCKER_GOOGLE_CREDENTIALS: ${HOME}/credentials.json - GOOGLE_PROJECT_ID: php-stackdriver - TAG: circle-${CIRCLE_BUILD_NUM} - -dependencies: - override: - - scripts/install_test_dependencies.sh - -test: - override: - - scripts/run_test_suite.sh diff --git a/cloudbuild.yaml b/cloudbuild.yaml index 9359c55..0f22ae2 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -1,38 +1,157 @@ -# This cloudbuild.yaml is used to test the php extension against multiple versions of php steps: - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=php:7.1', '.'] - id: php71-nts - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=php:7.1-zts', '.'] - id: php71-zts - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=php:7.0', '.'] - id: php70-nts - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=php:7.0-zts', '.'] - id: php70-zts - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=php:7.2', '.'] - id: php72-nts - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=php:7.2-zts', '.'] - id: php72-zts - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=gcr.io/google-appengine/php72', '.'] - id: php72-gae - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=gcr.io/google-appengine/php71', '.'] - id: php71-gae - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=gcr.io/google-appengine/php70', '.'] - id: php70-gae - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=gcr.io/php-stackdriver/php71-debug', '.'] - id: php71-debug - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=gcr.io/php-stackdriver/php71-32bit', '.'] - id: php71-32bit - - name: gcr.io/cloud-builders/docker - args: ['build', '--build-arg', 'BASE_IMAGE=gcr.io/php-stackdriver/php70-32bit', '.'] - id: php70-32bit +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=gcr.io/${_APPENGINE_PROJECT_ID}/php80' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php80-gae +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=gcr.io/${_APPENGINE_PROJECT_ID}/php74' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php74-gae +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=gcr.io/${_APPENGINE_PROJECT_ID}/php73' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php73-gae +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=php:8.0' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php80-nts +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=php:8.0-zts' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php80-zts +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=php:7.4' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php74-nts +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=php:7.4-zts' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php74-zts +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=php:7.3' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php73-nts +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=php:7.3-zts' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php73-zts +- name: gcr.io/cloud-builders/docker + args: + - 'build' + - '--build-arg' + - 'BASE_IMAGE=gcr.io/php-stackdriver/php71-debug' + - '--build-arg' + - 'GOOGLE_CREDENTIALS_BASE64=${_GOOGLE_CREDENTIALS_BASE64}' + - '--build-arg' + - 'CLOUDSDK_ACTIVE_CONFIG_NAME=${_CLOUDSDK_ACTIVE_CONFIG_NAME}' + - '--build-arg' + - 'GOOGLE_PROJECT_ID=${_GOOGLE_PROJECT_ID}' + - '--build-arg' + - 'PHP_DOCKER_GOOGLE_CREDENTIALS=${_PHP_DOCKER_GOOGLE_CREDENTIALS}' + - '.' + id: php71-debug +timeout: 2100s +substitutions: + _PHP_DOCKER_GOOGLE_CREDENTIALS: /build/gcp-creds.json + _APPENGINE_PROJECT_ID: google-appengine + _CLOUDSDK_ACTIVE_CONFIG_NAME: default + _GOOGLE_PROJECT_ID: $PROJECT_ID \ No newline at end of file diff --git a/docs/design.md b/docs/design.md index 24458a6..c3f4bb3 100644 --- a/docs/design.md +++ b/docs/design.md @@ -240,7 +240,7 @@ Validation will happen in 2 places. #### Disallowing Function Calls in Conditions and Expressions We will disallow all function calls except those that are explicitly marked as -safe. We maintain a list of build-in functions that are whitelisted. We also +safe. We maintain a list of build-in functions that are allowed. We also provide a `php.ini` setting that allows you to specify your own list of allowed function calls. diff --git a/php_stackdriver_debugger.h b/php_stackdriver_debugger.h index 2aef199..ec71e97 100644 --- a/php_stackdriver_debugger.h +++ b/php_stackdriver_debugger.h @@ -24,9 +24,9 @@ #include "php.h" #include "stackdriver_debugger.h" -#define PHP_STACKDRIVER_DEBUGGER_VERSION "0.2.0" +#define PHP_STACKDRIVER_DEBUGGER_VERSION "0.3.0" #define PHP_STACKDRIVER_DEBUGGER_EXTNAME "stackdriver_debugger" -#define PHP_STACKDRIVER_DEBUGGER_INI_WHITELISTED_FUNCTIONS "stackdriver_debugger.function_whitelist" +#define PHP_STACKDRIVER_DEBUGGER_INI_ALLOWED_FUNCTIONS "stackdriver_debugger.functions_allowed" #define PHP_STACKDRIVER_DEBUGGER_INI_MAX_TIME "stackdriver_debugger.max_time" #define PHP_STACKDRIVER_DEBUGGER_INI_MAX_TIME_PERCENTAGE "stackdriver_debugger.max_time_percentage" #define PHP_STACKDRIVER_DEBUGGER_INI_MAX_MEMORY "stackdriver_debugger.max_memory" @@ -43,7 +43,7 @@ PHP_RSHUTDOWN_FUNCTION(stackdriver_debugger); ZEND_BEGIN_MODULE_GLOBALS(stackdriver_debugger) /* map of function name -> empty null zval */ - HashTable *user_whitelisted_functions; + HashTable *user_allowed_functions; /* map of filename -> stackdriver_debugger_snapshot[] */ HashTable *snapshots_by_file; diff --git a/scripts/analyze_test.sh b/scripts/analyze_test.sh new file mode 100755 index 0000000..ab77a72 --- /dev/null +++ b/scripts/analyze_test.sh @@ -0,0 +1,32 @@ +#!/usr/bin/env bash +# Copyright 2018 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# A script for running functional tests + +set -e + +# PARAMS +# 1: path to phpt file associated with in tests/ +test=$1 + +testFile="${test%.*}.val" + +ZEND_DONT_UNLOAD_MODULES=1 USE_ZEND_ALLOC=0 valgrind \ + --leak-check=full \ + --show-reachable=yes \ + --track-origins=yes \ + /usr/bin/php \ + -dextension=/build/.libs/stackdriver_debugger.so \ + $1 > $testFile 2>&1 \ No newline at end of file diff --git a/scripts/install_test_dependencies.sh b/scripts/install_test_dependencies.sh index 3894fea..731ef4c 100755 --- a/scripts/install_test_dependencies.sh +++ b/scripts/install_test_dependencies.sh @@ -17,18 +17,6 @@ set -ex -if [ "${INSTALL_GCLOUD}" == "true" ]; then - # Install gcloud - if [ ! -d ${HOME}/gcloud/google-cloud-sdk ]; then - mkdir -p ${HOME}/gcloud && - wget https://dl.google.com/dl/cloudsdk/release/google-cloud-sdk.tar.gz --directory-prefix=${HOME}/gcloud && - cd "${HOME}/gcloud" && - tar xzf google-cloud-sdk.tar.gz && - ./google-cloud-sdk/install.sh --usage-reporting false --path-update false --command-completion false && - cd "${TEST_BUILD_DIR}"; - fi -fi - if [ -z "${CLOUDSDK_ACTIVE_CONFIG_NAME}" ]; then echo "You need to set CLOUDSDK_ACTIVE_CONFIG_NAME envvar." exit 1 @@ -64,13 +52,9 @@ fi gcloud auth activate-service-account \ --key-file "${PHP_DOCKER_GOOGLE_CREDENTIALS}" -if [ "${CIRCLECI}" == "true" ]; then - # Need sudo on circleci: - # https://discuss.circleci.com/t/gcloud-components-update-version-restriction/3725 - # They also overrides the PATH to use - # /opt/google-cloud-sdk/bin/gcloud so we can not easily use our - # own gcloud - sudo /opt/google-cloud-sdk/bin/gcloud -q components update beta -else - gcloud -q components update beta -fi +# https://cloud.google.com/sdk/docs/install +# Note: Updating and removing components using gcloud components is disabled +# if you installed Cloud SDK using apt-get or yum. +# +# To manage the Cloud SDK in this case, continue using the package management tool +# used during installation. diff --git a/scripts/run_test_suite.sh b/scripts/run_test_suite.sh index 4004859..c80204c 100755 --- a/scripts/run_test_suite.sh +++ b/scripts/run_test_suite.sh @@ -17,4 +17,11 @@ set -ex -gcloud container builds submit --config=cloudbuild.yaml . +if [ -z "${APPENGINE_PROJECT_ID}" ]; then + APPENGINE_PROJECT_ID="google-appengine" +fi + +gcloud builds submit \ + --config=cloudbuild.yaml \ + --substitutions=_APPENGINE_PROJECT_ID=$APPENGINE_PROJECT_ID,_GOOGLE_PROJECT_ID=$GOOGLE_PROJECT_ID,_GOOGLE_CREDENTIALS_BASE64=$GOOGLE_CREDENTIALS_BASE64,_PHP_DOCKER_GOOGLE_CREDENTIALS=$PHP_DOCKER_GOOGLE_CREDENTIALS,_CLOUDSDK_ACTIVE_CONFIG_NAME=$CLOUDSDK_ACTIVE_CONFIG_NAME \ + . diff --git a/stackdriver_debugger.c b/stackdriver_debugger.c index bc4a2f4..a2af378 100644 --- a/stackdriver_debugger.c +++ b/stackdriver_debugger.c @@ -55,16 +55,19 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_stackdriver_debugger_valid_statement, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, statement, IS_STRING, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_stackdriver_debugger_void, 0, 0, 0) +ZEND_END_ARG_INFO() + /* List of functions provided by this extension */ static zend_function_entry stackdriver_debugger_functions[] = { - PHP_FE(stackdriver_debugger_version, NULL) + PHP_FE(stackdriver_debugger_version, arginfo_stackdriver_debugger_void) PHP_FE(stackdriver_debugger_snapshot, arginfo_stackdriver_debugger_snapshot) PHP_FE(stackdriver_debugger_add_snapshot, arginfo_stackdriver_debugger_add_snapshot) - PHP_FE(stackdriver_debugger_list_snapshots, NULL) + PHP_FE(stackdriver_debugger_list_snapshots, arginfo_stackdriver_debugger_void) PHP_FE(stackdriver_debugger_logpoint, arginfo_stackdriver_debugger_logpoint) PHP_FE(stackdriver_debugger_add_logpoint, arginfo_stackdriver_debugger_add_logpoint) - PHP_FE(stackdriver_debugger_list_logpoints, NULL) + PHP_FE(stackdriver_debugger_list_logpoints, arginfo_stackdriver_debugger_void) PHP_FE(stackdriver_debugger_valid_statement, arginfo_stackdriver_debugger_valid_statement) PHP_FE_END }; @@ -100,7 +103,7 @@ PHP_INI_MH(OnUpdate_stackdriver_debugger_max_memory); /* Registers php.ini directives */ PHP_INI_BEGIN() - PHP_INI_ENTRY(PHP_STACKDRIVER_DEBUGGER_INI_WHITELISTED_FUNCTIONS, NULL, PHP_INI_ALL, OnUpdate_stackdriver_debugger_whitelisted_functions) + PHP_INI_ENTRY(PHP_STACKDRIVER_DEBUGGER_INI_ALLOWED_FUNCTIONS, NULL, PHP_INI_ALL, OnUpdate_stackdriver_debugger_allowed_functions) PHP_INI_ENTRY(PHP_STACKDRIVER_DEBUGGER_INI_MAX_TIME, "10", PHP_INI_ALL, NULL) PHP_INI_ENTRY(PHP_STACKDRIVER_DEBUGGER_INI_MAX_TIME_PERCENTAGE, "1", PHP_INI_ALL, NULL) PHP_INI_ENTRY(PHP_STACKDRIVER_DEBUGGER_INI_MAX_MEMORY, "10", PHP_INI_ALL, OnUpdate_stackdriver_debugger_max_memory) @@ -210,10 +213,16 @@ PHP_FUNCTION(stackdriver_debugger_list_logpoints) */ PHP_FUNCTION(stackdriver_debugger_valid_statement) { - zend_string *statement = NULL; + zend_string *statement; +#ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &statement) == FAILURE) { RETURN_FALSE; } +#else + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(statement); + ZEND_PARSE_PARAMETERS_END(); +#endif if (valid_debugger_statement(statement) != SUCCESS) { RETURN_FALSE; @@ -287,9 +296,15 @@ PHP_FUNCTION(stackdriver_debugger_snapshot) RETURN_FALSE; } +#ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &snapshot_id) == FAILURE) { RETURN_FALSE; } +#else + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(snapshot_id); + ZEND_PARSE_PARAMETERS_END(); +#endif start = stackdriver_debugger_now(); start_memory = zend_memory_usage(0); @@ -333,9 +348,15 @@ PHP_FUNCTION(stackdriver_debugger_logpoint) RETURN_FALSE; } +#ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "S", &logpoint_id) == FAILURE) { RETURN_FALSE; } +#else + ZEND_PARSE_PARAMETERS_START(1, 1) + Z_PARAM_STR(logpoint_id); + ZEND_PARSE_PARAMETERS_END(); +#endif start = stackdriver_debugger_now(); start_memory = zend_memory_usage(0); @@ -398,48 +419,51 @@ PHP_FUNCTION(stackdriver_debugger_add_snapshot) zval *zv = NULL, *callback = NULL; zend_long max_stack_eval_depth = 0; +#ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Sl|h", &filename, &lineno, &options) == FAILURE) { RETURN_FALSE; } +#else + ZEND_PARSE_PARAMETERS_START(2, 3) + Z_PARAM_STR(filename); + Z_PARAM_LONG(lineno); + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT(options); + ZEND_PARSE_PARAMETERS_END(); +#endif if (options != NULL) { - zv = zend_hash_str_find(options, "snapshotId", strlen("snapshotId")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "snapshotId", sizeof("snapshotId")-1)) != NULL && !Z_ISNULL_P(zv)) { snapshot_id = Z_STR_P(zv); } - zv = zend_hash_str_find(options, "condition", strlen("condition")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "condition", sizeof("condition")-1)) != NULL && !Z_ISNULL_P(zv)) { condition = Z_STR_P(zv); } - zv = zend_hash_str_find(options, "expressions", strlen("expressions")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "expressions", sizeof("expressions")-1)) != NULL && !Z_ISNULL_P(zv)) { expressions = Z_ARRVAL_P(zv); } - zv = zend_hash_str_find(options, "sourceRoot", strlen("sourceRoot")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "sourceRoot", sizeof("sourceRoot")-1)) != NULL && !Z_ISNULL_P(zv)) { source_root = Z_STR_P(zv); } - zv = zend_hash_str_find(options, "callback", strlen("callback")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "callback", sizeof("callback")-1)) != NULL && !Z_ISNULL_P(zv)) { callback = zv; } - zv = zend_hash_str_find(options, "maxDepth", strlen("maxDepth")); - if (zv != NULL && Z_TYPE_P(zv) == IS_LONG) { + if ((zv = zend_hash_str_find(options, "maxDepth", sizeof("maxDepth")-1)) != NULL && Z_TYPE_P(zv) == IS_LONG) { max_stack_eval_depth = Z_LVAL_P(zv); } } if (source_root == NULL) { source_root = EX(prev_execute_data)->func->op_array.filename; - char *current_file = estrndup(ZSTR_VAL(source_root), ZSTR_LEN(source_root)); - size_t dirlen = php_dirname(current_file, ZSTR_LEN(source_root)); - full_filename = stackdriver_debugger_full_filename(filename, current_file, dirlen); - efree(current_file); + zend_string *current_file = zend_string_init(ZSTR_VAL(source_root), ZSTR_LEN(source_root), 0); + size_t dirlen = php_dirname(ZSTR_VAL(current_file), ZSTR_LEN(source_root)); + full_filename = stackdriver_debugger_full_filename(filename, ZSTR_VAL(current_file), dirlen); + zend_string_release(current_file); } else { full_filename = stackdriver_debugger_full_filename(filename, ZSTR_VAL(source_root), ZSTR_LEN(source_root)); } @@ -480,43 +504,49 @@ PHP_FUNCTION(stackdriver_debugger_add_logpoint) HashTable *options = NULL, *expressions = NULL; zval *zv = NULL, *callback = NULL; +#ifndef FAST_ZPP if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "SlSS|h", &filename, &lineno, &log_level, &format, &options) == FAILURE) { RETURN_FALSE; } +#else + ZEND_PARSE_PARAMETERS_START(4, 5) + Z_PARAM_STR(filename); + Z_PARAM_LONG(lineno); + Z_PARAM_STR(log_level); + Z_PARAM_STR(format); + Z_PARAM_OPTIONAL + Z_PARAM_ARRAY_HT(options); + ZEND_PARSE_PARAMETERS_END(); +#endif if (options != NULL) { - zv = zend_hash_str_find(options, "snapshotId", strlen("snapshotId")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "snapshotId", strlen("snapshotId"))) != NULL && !Z_ISNULL_P(zv)) { snapshot_id = Z_STR_P(zv); } - zv = zend_hash_str_find(options, "condition", strlen("condition")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "condition", strlen("condition"))) != NULL && !Z_ISNULL_P(zv)) { condition = Z_STR_P(zv); } - zv = zend_hash_str_find(options, "expressions", strlen("expressions")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "expressions", strlen("expressions"))) != NULL && !Z_ISNULL_P(zv)) { expressions = Z_ARRVAL_P(zv); } - zv = zend_hash_str_find(options, "sourceRoot", strlen("sourceRoot")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "sourceRoot", strlen("sourceRoot"))) != NULL && !Z_ISNULL_P(zv)) { source_root = Z_STR_P(zv); } - zv = zend_hash_str_find(options, "callback", strlen("callback")); - if (zv != NULL && !Z_ISNULL_P(zv)) { + if ((zv = zend_hash_str_find(options, "callback", strlen("callback"))) != NULL && !Z_ISNULL_P(zv)) { callback = zv; } } if (source_root == NULL) { source_root = EX(prev_execute_data)->func->op_array.filename; - char *current_file = estrndup(ZSTR_VAL(source_root), ZSTR_LEN(source_root)); - size_t dirlen = php_dirname(current_file, ZSTR_LEN(source_root)); - full_filename = stackdriver_debugger_full_filename(filename, current_file, dirlen); - efree(current_file); + zend_string *current_file = zend_string_init(ZSTR_VAL(source_root), ZSTR_LEN(source_root), 0); + size_t dirlen = php_dirname(ZSTR_VAL(current_file), ZSTR_LEN(source_root)); + full_filename = stackdriver_debugger_full_filename(filename, ZSTR_VAL(current_file), dirlen); + zend_string_release(current_file); } else { full_filename = stackdriver_debugger_full_filename(filename, ZSTR_VAL(source_root), ZSTR_LEN(source_root)); } diff --git a/stackdriver_debugger_ast.c b/stackdriver_debugger_ast.c index 6e86935..7c1aa29 100644 --- a/stackdriver_debugger_ast.c +++ b/stackdriver_debugger_ast.c @@ -27,11 +27,15 @@ static void (*original_zend_ast_process)(zend_ast*); /* map of function name -> empty null zval */ -static HashTable global_whitelisted_functions; +static HashTable global_allowed_functions; /* map of filename -> (map of breakpoint id -> nil) */ static HashTable registered_breakpoints; +static inline size_t ast_list_size(uint32_t children) { + return sizeof(zend_ast_list) - sizeof(zend_ast *) + sizeof(zend_ast *) * children; +} + /** * This method generates a new abstract syntax tree that injects a function * call to `stackdriver_debugger()`. @@ -55,19 +59,19 @@ static HashTable registered_breakpoints; static zend_ast_list *create_debugger_ast(const char *callback, zend_string *breakpoint_id, uint32_t lineno) { zend_ast *new_call; - zend_ast_zval *var, *snapshot_id; + zend_ast_zval *var = NULL, *snapshot_id = NULL; zend_ast_list *new_list, *arg_list; var = emalloc(sizeof(zend_ast_zval)); var->kind = ZEND_AST_ZVAL; ZVAL_STRING(&var->val, callback); - var->val.u2.lineno = lineno; + Z_LINENO(var->val) = lineno; zend_hash_next_index_insert_ptr(STACKDRIVER_DEBUGGER_G(ast_to_clean), var); snapshot_id = emalloc(sizeof(zend_ast_zval)); snapshot_id->kind = ZEND_AST_ZVAL; ZVAL_STR(&snapshot_id->val, breakpoint_id); - snapshot_id->val.u2.lineno = lineno; + Z_LINENO(snapshot_id->val) = lineno; zend_hash_next_index_insert_ptr(STACKDRIVER_DEBUGGER_G(ast_to_clean), snapshot_id); arg_list = emalloc(sizeof(zend_ast_list) + sizeof(zend_ast*)); @@ -111,7 +115,7 @@ static int inject_ast(zend_ast *ast, zend_ast_list *to_insert) zend_ast_decl *decl; zend_ast_zval *azval; - if (ast == NULL) { + if (ast == NULL || to_insert == NULL) { return FAILURE; } @@ -216,7 +220,7 @@ static void fill_breakpoint_ids(zval *array, HashTable *breakpoints) int i; zend_string *breakpoint_id, *breakpoint_id2; ZEND_HASH_FOREACH_KEY(breakpoints, i, breakpoint_id) { - breakpoint_id2 = zend_string_dup(breakpoint_id, 0); + breakpoint_id2 = zend_string_init(ZSTR_VAL(breakpoint_id), ZSTR_LEN(breakpoint_id), 0); add_next_index_str(array, breakpoint_id2); } ZEND_HASH_FOREACH_END(); } @@ -267,7 +271,7 @@ static void reset_registered_breakpoints_for_filename(zend_string *filename) * Persistent string dup as the filename is request based and we need * it to live between requests. */ - filename2 = zend_string_dup(filename, 1); + filename2 = zend_string_init(ZSTR_VAL(filename), ZSTR_LEN(filename), 1); /* Use malloc directly because we are not handling a request */ breakpoints = malloc(sizeof(HashTable)); @@ -278,7 +282,7 @@ static void reset_registered_breakpoints_for_filename(zend_string *filename) static void register_breakpoint_id(zend_string *filename, zend_string *id) { - zend_string *id2 = zend_string_dup(id, 1); + zend_string *id2 = zend_string_init(ZSTR_VAL(id), ZSTR_LEN(id), 1); HashTable *breakpoints = zend_hash_find_ptr(®istered_breakpoints, filename); zend_hash_add_empty_element(breakpoints, id2); } @@ -292,7 +296,7 @@ void stackdriver_debugger_ast_process(zend_ast *ast) HashTable *ht; stackdriver_debugger_snapshot_t *snapshot; stackdriver_debugger_logpoint_t *logpoint; - zend_ast_list *to_insert; + zend_ast_list *to_insert = NULL; zend_string *filename = zend_get_compiled_filename(); zval *snapshots = zend_hash_find(STACKDRIVER_DEBUGGER_G(snapshots_by_file), filename); @@ -323,15 +327,17 @@ void stackdriver_debugger_ast_process(zend_ast *ast) ht = Z_ARR_P(logpoints); ZEND_HASH_FOREACH_PTR(ht, logpoint) { - to_insert = create_debugger_ast( - "stackdriver_debugger_logpoint", - logpoint->id, - logpoint->lineno - ); - if (inject_ast(ast, to_insert) == SUCCESS) { - register_breakpoint_id(filename, logpoint->id); - } else { - // failed to insert + if (logpoint != NULL && logpoint->id != NULL) { + to_insert = create_debugger_ast( + "stackdriver_debugger_logpoint", + logpoint->id, + logpoint->lineno + ); + if (ast != NULL && to_insert != NULL && inject_ast(ast, to_insert) == SUCCESS) { + register_breakpoint_id(filename, logpoint->id); + } else { + // failed to insert + } } } ZEND_HASH_FOREACH_END(); } @@ -349,19 +355,23 @@ static int compile_ast(zend_string *source, zend_ast **ast_p, zend_lex_state *or { zval source_zval; - ZVAL_STR(&source_zval, source); - Z_TRY_ADDREF(source_zval); + ZVAL_STR_COPY(&source_zval, source); zend_save_lexical_state(original_lex_state); - if (zend_prepare_string_for_scanning(&source_zval, "") == FAILURE) { - zend_restore_lexical_state(original_lex_state); - return FAILURE; - } + zend_prepare_string_for_scanning(&source_zval, ""); + // if (zend_prepare_string_for_scanning(&source_zval, "") == FAILURE) { + // zend_restore_lexical_state(original_lex_state); + // return FAILURE; + // } CG(ast) = NULL; CG(ast_arena) = zend_arena_create(1024 * 32); + #if PHP_VERSION_ID < 70400 zval_dtor(&source_zval); + #else + zval_ptr_dtor_str(&source_zval); + #endif if (zendparse() != 0) { /* Error parsing the string */ @@ -384,16 +394,16 @@ static int compile_ast(zend_string *source, zend_ast **ast_p, zend_lex_state *or } /** - * Determine if the allowed function call is whitelisted. + * Determine if the function call is allowed. */ static int valid_debugger_call(zend_string *function_name) { - if (zend_hash_find(&global_whitelisted_functions, function_name) != NULL) { + if (zend_hash_find(&global_allowed_functions, function_name) != NULL) { return SUCCESS; } - if (STACKDRIVER_DEBUGGER_G(user_whitelisted_functions) && - zend_hash_find(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions), function_name) != NULL) { + if (STACKDRIVER_DEBUGGER_G(user_allowed_functions) && + zend_hash_find(STACKDRIVER_DEBUGGER_G(user_allowed_functions), function_name) != NULL) { return SUCCESS; } @@ -563,265 +573,265 @@ int valid_debugger_statement(zend_string *statement) return SUCCESS; } -static void register_user_whitelisted_functions_str(const char *str, int len) +static void register_user_allowed_functions_str(const char *str, int len) { char *key = NULL, *last = NULL; char *tmp = estrndup(str, len); for (key = php_strtok_r(tmp, ",", &last); key; key = php_strtok_r(NULL, ",", &last)) { - zend_hash_str_add_empty_element(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions), key, strlen(key)); + zend_hash_str_add_empty_element(STACKDRIVER_DEBUGGER_G(user_allowed_functions), key, strlen(key)); } efree(tmp); } -static void register_user_whitelisted_functions(zend_string *ini_setting) +static void register_user_allowed_functions(zend_string *ini_setting) { - register_user_whitelisted_functions_str(ZSTR_VAL(ini_setting), ZSTR_LEN(ini_setting)); + register_user_allowed_functions_str(ZSTR_VAL(ini_setting), ZSTR_LEN(ini_setting)); } -#define WHITELIST_FUNCTION(function_name) zend_hash_str_add_empty_element(ht, function_name, strlen(function_name)) +#define ALLOW_FUNCTION(function_name) zend_hash_str_add_empty_element(ht, function_name, strlen(function_name)) /* * Registers a hard-coded list of functions to allow in conditions and * expressions. */ -static int register_whitelisted_functions(HashTable *ht) +static int register_allowed_functions(HashTable *ht) { /* Array functions */ - WHITELIST_FUNCTION("array_change_key_case"); - WHITELIST_FUNCTION("array_chunk"); - WHITELIST_FUNCTION("array_column"); - WHITELIST_FUNCTION("array_combine"); - WHITELIST_FUNCTION("array_count_values"); - WHITELIST_FUNCTION("array_diff_assoc"); - WHITELIST_FUNCTION("array_diff_key"); - WHITELIST_FUNCTION("array_diff_uassoc"); - WHITELIST_FUNCTION("array_diff_ukey"); - WHITELIST_FUNCTION("array_diff"); - WHITELIST_FUNCTION("array_fill_keys"); - WHITELIST_FUNCTION("array_fill"); - WHITELIST_FUNCTION("array_filter"); - WHITELIST_FUNCTION("array_flip"); - WHITELIST_FUNCTION("array_intersect_assoc"); - WHITELIST_FUNCTION("array_intersect_key"); - WHITELIST_FUNCTION("array_intersect_uassoc"); - WHITELIST_FUNCTION("array_intersect_ukey"); - WHITELIST_FUNCTION("array_key_exists"); - WHITELIST_FUNCTION("array_keys"); - WHITELIST_FUNCTION("array_map"); - WHITELIST_FUNCTION("array_merge_recursive"); - WHITELIST_FUNCTION("array_merge"); - WHITELIST_FUNCTION("array_multisort"); - WHITELIST_FUNCTION("array_pad"); - WHITELIST_FUNCTION("array_product"); - WHITELIST_FUNCTION("array_rand"); - WHITELIST_FUNCTION("array_reduce"); - WHITELIST_FUNCTION("array_replace_recursive"); - WHITELIST_FUNCTION("array_replace"); - WHITELIST_FUNCTION("array_reverse"); - WHITELIST_FUNCTION("array_search"); - WHITELIST_FUNCTION("array_slice"); - WHITELIST_FUNCTION("array_splice"); - WHITELIST_FUNCTION("array_sum"); - WHITELIST_FUNCTION("array_udiff_assoc"); - WHITELIST_FUNCTION("array_udiff_uassoc"); - WHITELIST_FUNCTION("array_udiff"); - WHITELIST_FUNCTION("array_uintersect_assoc"); - WHITELIST_FUNCTION("array_uintersect_uassoc"); - WHITELIST_FUNCTION("array_uintersect"); - WHITELIST_FUNCTION("array_unique"); - WHITELIST_FUNCTION("array_values"); - WHITELIST_FUNCTION("array_walk_recursive"); - WHITELIST_FUNCTION("array_walk"); - WHITELIST_FUNCTION("compact"); - WHITELIST_FUNCTION("count"); - WHITELIST_FUNCTION("current"); - WHITELIST_FUNCTION("in_array"); - WHITELIST_FUNCTION("key_exists"); - WHITELIST_FUNCTION("key"); - WHITELIST_FUNCTION("pos"); - WHITELIST_FUNCTION("range"); - WHITELIST_FUNCTION("sizeof"); + ALLOW_FUNCTION("array_change_key_case"); + ALLOW_FUNCTION("array_chunk"); + ALLOW_FUNCTION("array_column"); + ALLOW_FUNCTION("array_combine"); + ALLOW_FUNCTION("array_count_values"); + ALLOW_FUNCTION("array_diff_assoc"); + ALLOW_FUNCTION("array_diff_key"); + ALLOW_FUNCTION("array_diff_uassoc"); + ALLOW_FUNCTION("array_diff_ukey"); + ALLOW_FUNCTION("array_diff"); + ALLOW_FUNCTION("array_fill_keys"); + ALLOW_FUNCTION("array_fill"); + ALLOW_FUNCTION("array_filter"); + ALLOW_FUNCTION("array_flip"); + ALLOW_FUNCTION("array_intersect_assoc"); + ALLOW_FUNCTION("array_intersect_key"); + ALLOW_FUNCTION("array_intersect_uassoc"); + ALLOW_FUNCTION("array_intersect_ukey"); + ALLOW_FUNCTION("array_key_exists"); + ALLOW_FUNCTION("array_keys"); + ALLOW_FUNCTION("array_map"); + ALLOW_FUNCTION("array_merge_recursive"); + ALLOW_FUNCTION("array_merge"); + ALLOW_FUNCTION("array_multisort"); + ALLOW_FUNCTION("array_pad"); + ALLOW_FUNCTION("array_product"); + ALLOW_FUNCTION("array_rand"); + ALLOW_FUNCTION("array_reduce"); + ALLOW_FUNCTION("array_replace_recursive"); + ALLOW_FUNCTION("array_replace"); + ALLOW_FUNCTION("array_reverse"); + ALLOW_FUNCTION("array_search"); + ALLOW_FUNCTION("array_slice"); + ALLOW_FUNCTION("array_splice"); + ALLOW_FUNCTION("array_sum"); + ALLOW_FUNCTION("array_udiff_assoc"); + ALLOW_FUNCTION("array_udiff_uassoc"); + ALLOW_FUNCTION("array_udiff"); + ALLOW_FUNCTION("array_uintersect_assoc"); + ALLOW_FUNCTION("array_uintersect_uassoc"); + ALLOW_FUNCTION("array_uintersect"); + ALLOW_FUNCTION("array_unique"); + ALLOW_FUNCTION("array_values"); + ALLOW_FUNCTION("array_walk_recursive"); + ALLOW_FUNCTION("array_walk"); + ALLOW_FUNCTION("compact"); + ALLOW_FUNCTION("count"); + ALLOW_FUNCTION("current"); + ALLOW_FUNCTION("in_array"); + ALLOW_FUNCTION("key_exists"); + ALLOW_FUNCTION("key"); + ALLOW_FUNCTION("pos"); + ALLOW_FUNCTION("range"); + ALLOW_FUNCTION("sizeof"); /* Class functions */ - WHITELIST_FUNCTION("class_exists"); - WHITELIST_FUNCTION("get_called_class"); - WHITELIST_FUNCTION("get_class_methods"); - WHITELIST_FUNCTION("get_class_vars"); - WHITELIST_FUNCTION("get_class"); - WHITELIST_FUNCTION("get_declared_classes"); - WHITELIST_FUNCTION("get_declared_interfaces"); - WHITELIST_FUNCTION("get_declared_traits"); - WHITELIST_FUNCTION("get_object_vars"); - WHITELIST_FUNCTION("get_parent_class"); - WHITELIST_FUNCTION("interface_exists"); - WHITELIST_FUNCTION("is_a"); - WHITELIST_FUNCTION("is_subclass_of"); - WHITELIST_FUNCTION("method_exists"); - WHITELIST_FUNCTION("property_exists"); - WHITELIST_FUNCTION("trait_exists"); + ALLOW_FUNCTION("class_exists"); + ALLOW_FUNCTION("get_called_class"); + ALLOW_FUNCTION("get_class_methods"); + ALLOW_FUNCTION("get_class_vars"); + ALLOW_FUNCTION("get_class"); + ALLOW_FUNCTION("get_declared_classes"); + ALLOW_FUNCTION("get_declared_interfaces"); + ALLOW_FUNCTION("get_declared_traits"); + ALLOW_FUNCTION("get_object_vars"); + ALLOW_FUNCTION("get_parent_class"); + ALLOW_FUNCTION("interface_exists"); + ALLOW_FUNCTION("is_a"); + ALLOW_FUNCTION("is_subclass_of"); + ALLOW_FUNCTION("method_exists"); + ALLOW_FUNCTION("property_exists"); + ALLOW_FUNCTION("trait_exists"); /* Configuration handling: http://php.net/manual/en/ref.info.php */ - WHITELIST_FUNCTION("extension_loaded"); - WHITELIST_FUNCTION("gc_enabled"); - WHITELIST_FUNCTION("get_cfg_var"); - WHITELIST_FUNCTION("get_current_user"); - WHITELIST_FUNCTION("get_defined_constants"); - WHITELIST_FUNCTION("get_extension_funcs"); - WHITELIST_FUNCTION("get_include_path"); - WHITELIST_FUNCTION("get_included_files"); - WHITELIST_FUNCTION("get_loaded_extensions"); - WHITELIST_FUNCTION("get_magic_quotes_gpc"); - WHITELIST_FUNCTION("get_magic_quotes_runtime"); - WHITELIST_FUNCTION("get_required_files"); - WHITELIST_FUNCTION("get_resoruces"); - WHITELIST_FUNCTION("getenv"); - WHITELIST_FUNCTION("getlastmod"); - WHITELIST_FUNCTION("getmygid"); - WHITELIST_FUNCTION("getmyinode"); - WHITELIST_FUNCTION("getmypid"); - WHITELIST_FUNCTION("getmyuid"); - WHITELIST_FUNCTION("getrusage"); - WHITELIST_FUNCTION("ini_get_all"); - WHITELIST_FUNCTION("ini_get"); - WHITELIST_FUNCTION("memory_get_peak_usage"); - WHITELIST_FUNCTION("memory_get_usage"); - WHITELIST_FUNCTION("php_ini_loaded_file"); - WHITELIST_FUNCTION("php_ini_scanned_files"); - WHITELIST_FUNCTION("php_logo_guid"); - WHITELIST_FUNCTION("php_sapi_name"); - WHITELIST_FUNCTION("php_uname"); - WHITELIST_FUNCTION("phpversion"); - WHITELIST_FUNCTION("sys_get_temp_dir"); - WHITELIST_FUNCTION("version_compare"); - WHITELIST_FUNCTION("zend_logo_guid"); - WHITELIST_FUNCTION("zend_thread_id"); - WHITELIST_FUNCTION("zend_version"); + ALLOW_FUNCTION("extension_loaded"); + ALLOW_FUNCTION("gc_enabled"); + ALLOW_FUNCTION("get_cfg_var"); + ALLOW_FUNCTION("get_current_user"); + ALLOW_FUNCTION("get_defined_constants"); + ALLOW_FUNCTION("get_extension_funcs"); + ALLOW_FUNCTION("get_include_path"); + ALLOW_FUNCTION("get_included_files"); + ALLOW_FUNCTION("get_loaded_extensions"); + ALLOW_FUNCTION("get_magic_quotes_gpc"); + ALLOW_FUNCTION("get_magic_quotes_runtime"); + ALLOW_FUNCTION("get_required_files"); + ALLOW_FUNCTION("get_resoruces"); + ALLOW_FUNCTION("getenv"); + ALLOW_FUNCTION("getlastmod"); + ALLOW_FUNCTION("getmygid"); + ALLOW_FUNCTION("getmyinode"); + ALLOW_FUNCTION("getmypid"); + ALLOW_FUNCTION("getmyuid"); + ALLOW_FUNCTION("getrusage"); + ALLOW_FUNCTION("ini_get_all"); + ALLOW_FUNCTION("ini_get"); + ALLOW_FUNCTION("memory_get_peak_usage"); + ALLOW_FUNCTION("memory_get_usage"); + ALLOW_FUNCTION("php_ini_loaded_file"); + ALLOW_FUNCTION("php_ini_scanned_files"); + ALLOW_FUNCTION("php_logo_guid"); + ALLOW_FUNCTION("php_sapi_name"); + ALLOW_FUNCTION("php_uname"); + ALLOW_FUNCTION("phpversion"); + ALLOW_FUNCTION("sys_get_temp_dir"); + ALLOW_FUNCTION("version_compare"); + ALLOW_FUNCTION("zend_logo_guid"); + ALLOW_FUNCTION("zend_thread_id"); + ALLOW_FUNCTION("zend_version"); /* Function handling: http://php.net/manual/en/book.funchand.php */ - WHITELIST_FUNCTION("func_get_arg"); - WHITELIST_FUNCTION("func_get_args"); - WHITELIST_FUNCTION("func_num_args"); - WHITELIST_FUNCTION("function_exists"); - WHITELIST_FUNCTION("get_defined_function"); + ALLOW_FUNCTION("func_get_arg"); + ALLOW_FUNCTION("func_get_args"); + ALLOW_FUNCTION("func_num_args"); + ALLOW_FUNCTION("function_exists"); + ALLOW_FUNCTION("get_defined_function"); /* String handling: */ - WHITELIST_FUNCTION("addcslashes"); - WHITELIST_FUNCTION("addslashes"); - WHITELIST_FUNCTION("bin2hex"); - WHITELIST_FUNCTION("chop"); - WHITELIST_FUNCTION("chr"); - WHITELIST_FUNCTION("chunk_split"); - WHITELIST_FUNCTION("convert_cyr_string"); - WHITELIST_FUNCTION("convert_uudecode"); - WHITELIST_FUNCTION("convert_uuencode"); - WHITELIST_FUNCTION("count_chars"); - WHITELIST_FUNCTION("crc32"); - WHITELIST_FUNCTION("crypt"); - WHITELIST_FUNCTION("explode"); - WHITELIST_FUNCTION("get_html_translation_table"); - WHITELIST_FUNCTION("hebrev"); - WHITELIST_FUNCTION("hebrevc"); - WHITELIST_FUNCTION("hex2bin"); - WHITELIST_FUNCTION("html_entity_decode"); - WHITELIST_FUNCTION("htmlentities"); - WHITELIST_FUNCTION("htmlspecialchars_decode"); - WHITELIST_FUNCTION("html_specialchars"); - WHITELIST_FUNCTION("implode"); - WHITELIST_FUNCTION("join"); - WHITELIST_FUNCTION("lcfirst"); - WHITELIST_FUNCTION("levenshtein"); - WHITELIST_FUNCTION("localeconv"); - WHITELIST_FUNCTION("ltrim"); - WHITELIST_FUNCTION("md5file"); - WHITELIST_FUNCTION("md5"); - WHITELIST_FUNCTION("metaphone"); - WHITELIST_FUNCTION("money_format"); - WHITELIST_FUNCTION("nl_langinfo"); - WHITELIST_FUNCTION("nl2br"); - WHITELIST_FUNCTION("number_format"); - WHITELIST_FUNCTION("ord"); - WHITELIST_FUNCTION("quoted_printable_decode"); - WHITELIST_FUNCTION("quoted_printable_encode"); - WHITELIST_FUNCTION("quotemeta"); - WHITELIST_FUNCTION("rtrim"); - WHITELIST_FUNCTION("sha1_file"); - WHITELIST_FUNCTION("sha1"); - WHITELIST_FUNCTION("soundex"); - WHITELIST_FUNCTION("sprintf"); - WHITELIST_FUNCTION("str_getcsv"); - WHITELIST_FUNCTION("str_pad"); - WHITELIST_FUNCTION("str_repeat"); - WHITELIST_FUNCTION("str_rot13"); - WHITELIST_FUNCTION("str_shuffle"); - WHITELIST_FUNCTION("str_split"); - WHITELIST_FUNCTION("str_word_count"); - WHITELIST_FUNCTION("strcasecmp"); - WHITELIST_FUNCTION("strchr"); - WHITELIST_FUNCTION("strcmp"); - WHITELIST_FUNCTION("strcoll"); - WHITELIST_FUNCTION("strcspn"); - WHITELIST_FUNCTION("strip_tags"); - WHITELIST_FUNCTION("stripcslashes"); - WHITELIST_FUNCTION("stripos"); - WHITELIST_FUNCTION("stripslashes"); - WHITELIST_FUNCTION("stristr"); - WHITELIST_FUNCTION("strlen"); - WHITELIST_FUNCTION("strnatcasecmp"); - WHITELIST_FUNCTION("strnatcmp"); - WHITELIST_FUNCTION("strncasecmp"); - WHITELIST_FUNCTION("strncmp"); - WHITELIST_FUNCTION("strpbrk"); - WHITELIST_FUNCTION("strpos"); - WHITELIST_FUNCTION("strrchr"); - WHITELIST_FUNCTION("strrev"); - WHITELIST_FUNCTION("strripos"); - WHITELIST_FUNCTION("strrpos"); - WHITELIST_FUNCTION("strspn"); - WHITELIST_FUNCTION("strstr"); - WHITELIST_FUNCTION("strtok"); - WHITELIST_FUNCTION("strtolower"); - WHITELIST_FUNCTION("strtoupper"); - WHITELIST_FUNCTION("strtr"); - WHITELIST_FUNCTION("substr_compare"); - WHITELIST_FUNCTION("substr_count"); - WHITELIST_FUNCTION("substr_replace"); - WHITELIST_FUNCTION("substr"); - WHITELIST_FUNCTION("trim"); - WHITELIST_FUNCTION("ucfirst"); - WHITELIST_FUNCTION("ucwords"); - WHITELIST_FUNCTION("wordwrap"); + ALLOW_FUNCTION("addcslashes"); + ALLOW_FUNCTION("addslashes"); + ALLOW_FUNCTION("bin2hex"); + ALLOW_FUNCTION("chop"); + ALLOW_FUNCTION("chr"); + ALLOW_FUNCTION("chunk_split"); + ALLOW_FUNCTION("convert_cyr_string"); + ALLOW_FUNCTION("convert_uudecode"); + ALLOW_FUNCTION("convert_uuencode"); + ALLOW_FUNCTION("count_chars"); + ALLOW_FUNCTION("crc32"); + ALLOW_FUNCTION("crypt"); + ALLOW_FUNCTION("explode"); + ALLOW_FUNCTION("get_html_translation_table"); + ALLOW_FUNCTION("hebrev"); + ALLOW_FUNCTION("hebrevc"); + ALLOW_FUNCTION("hex2bin"); + ALLOW_FUNCTION("html_entity_decode"); + ALLOW_FUNCTION("htmlentities"); + ALLOW_FUNCTION("htmlspecialchars_decode"); + ALLOW_FUNCTION("html_specialchars"); + ALLOW_FUNCTION("implode"); + ALLOW_FUNCTION("join"); + ALLOW_FUNCTION("lcfirst"); + ALLOW_FUNCTION("levenshtein"); + ALLOW_FUNCTION("localeconv"); + ALLOW_FUNCTION("ltrim"); + ALLOW_FUNCTION("md5file"); + ALLOW_FUNCTION("md5"); + ALLOW_FUNCTION("metaphone"); + ALLOW_FUNCTION("money_format"); + ALLOW_FUNCTION("nl_langinfo"); + ALLOW_FUNCTION("nl2br"); + ALLOW_FUNCTION("number_format"); + ALLOW_FUNCTION("ord"); + ALLOW_FUNCTION("quoted_printable_decode"); + ALLOW_FUNCTION("quoted_printable_encode"); + ALLOW_FUNCTION("quotemeta"); + ALLOW_FUNCTION("rtrim"); + ALLOW_FUNCTION("sha1_file"); + ALLOW_FUNCTION("sha1"); + ALLOW_FUNCTION("soundex"); + ALLOW_FUNCTION("sprintf"); + ALLOW_FUNCTION("str_getcsv"); + ALLOW_FUNCTION("str_pad"); + ALLOW_FUNCTION("str_repeat"); + ALLOW_FUNCTION("str_rot13"); + ALLOW_FUNCTION("str_shuffle"); + ALLOW_FUNCTION("str_split"); + ALLOW_FUNCTION("str_word_count"); + ALLOW_FUNCTION("strcasecmp"); + ALLOW_FUNCTION("strchr"); + ALLOW_FUNCTION("strcmp"); + ALLOW_FUNCTION("strcoll"); + ALLOW_FUNCTION("strcspn"); + ALLOW_FUNCTION("strip_tags"); + ALLOW_FUNCTION("stripcslashes"); + ALLOW_FUNCTION("stripos"); + ALLOW_FUNCTION("stripslashes"); + ALLOW_FUNCTION("stristr"); + ALLOW_FUNCTION("strlen"); + ALLOW_FUNCTION("strnatcasecmp"); + ALLOW_FUNCTION("strnatcmp"); + ALLOW_FUNCTION("strncasecmp"); + ALLOW_FUNCTION("strncmp"); + ALLOW_FUNCTION("strpbrk"); + ALLOW_FUNCTION("strpos"); + ALLOW_FUNCTION("strrchr"); + ALLOW_FUNCTION("strrev"); + ALLOW_FUNCTION("strripos"); + ALLOW_FUNCTION("strrpos"); + ALLOW_FUNCTION("strspn"); + ALLOW_FUNCTION("strstr"); + ALLOW_FUNCTION("strtok"); + ALLOW_FUNCTION("strtolower"); + ALLOW_FUNCTION("strtoupper"); + ALLOW_FUNCTION("strtr"); + ALLOW_FUNCTION("substr_compare"); + ALLOW_FUNCTION("substr_count"); + ALLOW_FUNCTION("substr_replace"); + ALLOW_FUNCTION("substr"); + ALLOW_FUNCTION("trim"); + ALLOW_FUNCTION("ucfirst"); + ALLOW_FUNCTION("ucwords"); + ALLOW_FUNCTION("wordwrap"); /* Variable handling: http://php.net/manual/en/book.var.php */ - WHITELIST_FUNCTION("boolval"); - WHITELIST_FUNCTION("doubleval"); - WHITELIST_FUNCTION("empty"); - WHITELIST_FUNCTION("float_val"); - WHITELIST_FUNCTION("get_defined_vars"); - WHITELIST_FUNCTION("get_resource_type"); - WHITELIST_FUNCTION("gettype"); - WHITELIST_FUNCTION("intval"); - WHITELIST_FUNCTION("is_array"); - WHITELIST_FUNCTION("is_bool"); - WHITELIST_FUNCTION("is_callable"); - WHITELIST_FUNCTION("is_double"); - WHITELIST_FUNCTION("is_float"); - WHITELIST_FUNCTION("is_int"); - WHITELIST_FUNCTION("is_integer"); - WHITELIST_FUNCTION("is_iterable"); - WHITELIST_FUNCTION("is_long"); - WHITELIST_FUNCTION("is_null"); - WHITELIST_FUNCTION("is_numeric"); - WHITELIST_FUNCTION("is_object"); - WHITELIST_FUNCTION("is_real"); - WHITELIST_FUNCTION("is_resource"); - WHITELIST_FUNCTION("is_scalar"); - WHITELIST_FUNCTION("is_string"); - WHITELIST_FUNCTION("isset"); - WHITELIST_FUNCTION("serialize"); - WHITELIST_FUNCTION("settype"); - WHITELIST_FUNCTION("strval"); - WHITELIST_FUNCTION("unserialize"); + ALLOW_FUNCTION("boolval"); + ALLOW_FUNCTION("doubleval"); + ALLOW_FUNCTION("empty"); + ALLOW_FUNCTION("float_val"); + ALLOW_FUNCTION("get_defined_vars"); + ALLOW_FUNCTION("get_resource_type"); + ALLOW_FUNCTION("gettype"); + ALLOW_FUNCTION("intval"); + ALLOW_FUNCTION("is_array"); + ALLOW_FUNCTION("is_bool"); + ALLOW_FUNCTION("is_callable"); + ALLOW_FUNCTION("is_double"); + ALLOW_FUNCTION("is_float"); + ALLOW_FUNCTION("is_int"); + ALLOW_FUNCTION("is_integer"); + ALLOW_FUNCTION("is_iterable"); + ALLOW_FUNCTION("is_long"); + ALLOW_FUNCTION("is_null"); + ALLOW_FUNCTION("is_numeric"); + ALLOW_FUNCTION("is_object"); + ALLOW_FUNCTION("is_real"); + ALLOW_FUNCTION("is_resource"); + ALLOW_FUNCTION("is_scalar"); + ALLOW_FUNCTION("is_string"); + ALLOW_FUNCTION("isset"); + ALLOW_FUNCTION("serialize"); + ALLOW_FUNCTION("settype"); + ALLOW_FUNCTION("strval"); + ALLOW_FUNCTION("unserialize"); return SUCCESS; } @@ -833,16 +843,16 @@ static void ast_to_clean_dtor(zval *zv) } /** - * Request initialization lifecycle hook. Sets up the function whitelist. + * Request initialization lifecycle hook. Sets up the allowed functions list. */ int stackdriver_debugger_ast_rinit(TSRMLS_D) { - ALLOC_HASHTABLE(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions)); - zend_hash_init(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions), 8, NULL, ZVAL_PTR_DTOR, 1); + ALLOC_HASHTABLE(STACKDRIVER_DEBUGGER_G(user_allowed_functions)); + zend_hash_init(STACKDRIVER_DEBUGGER_G(user_allowed_functions), 8, NULL, ZVAL_PTR_DTOR, 1); - char *ini = INI_STR(PHP_STACKDRIVER_DEBUGGER_INI_WHITELISTED_FUNCTIONS); + char *ini = INI_STR(PHP_STACKDRIVER_DEBUGGER_INI_ALLOWED_FUNCTIONS); if (ini) { - register_user_whitelisted_functions_str(ini, strlen(ini)); + register_user_allowed_functions_str(ini, strlen(ini)); } ALLOC_HASHTABLE(STACKDRIVER_DEBUGGER_G(ast_to_clean)); @@ -852,12 +862,12 @@ int stackdriver_debugger_ast_rinit(TSRMLS_D) } /** - * Request shutdown lifecycle hook. Cleans up the function whitelist. + * Request shutdown lifecycle hook. Cleans up the allowed functions list. */ int stackdriver_debugger_ast_rshutdown(TSRMLS_D) { - zend_hash_destroy(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions)); - FREE_HASHTABLE(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions)); + zend_hash_destroy(STACKDRIVER_DEBUGGER_G(user_allowed_functions)); + FREE_HASHTABLE(STACKDRIVER_DEBUGGER_G(user_allowed_functions)); zend_hash_destroy(STACKDRIVER_DEBUGGER_G(ast_to_clean)); FREE_HASHTABLE(STACKDRIVER_DEBUGGER_G(ast_to_clean)); @@ -894,9 +904,9 @@ int stackdriver_debugger_ast_minit(INIT_FUNC_ARGS) original_zend_ast_process = zend_ast_process; zend_ast_process = stackdriver_debugger_ast_process; - /* Setup storage for whitelisted functions */ - zend_hash_init(&global_whitelisted_functions, 1024, NULL, ZVAL_PTR_DTOR, 1); - register_whitelisted_functions(&global_whitelisted_functions); + /* Setup storage for allowed functions */ + zend_hash_init(&global_allowed_functions, 1024, NULL, ZVAL_PTR_DTOR, 1); + register_allowed_functions(&global_allowed_functions); /* Setup storage for breakpoints by filename */ zend_hash_init(®istered_breakpoints, 64, NULL, breakpoints_dtor, 1); @@ -910,22 +920,22 @@ int stackdriver_debugger_ast_minit(INIT_FUNC_ARGS) int stackdriver_debugger_ast_mshutdown(SHUTDOWN_FUNC_ARGS) { zend_ast_process = original_zend_ast_process; - zend_hash_destroy(&global_whitelisted_functions); + zend_hash_destroy(&global_allowed_functions); zend_hash_destroy(®istered_breakpoints); return SUCCESS; } /** - * Callback for when the user changes the function whitelist php.ini setting. + * Callback for when the user changes the allowed functions list php.ini setting. */ -PHP_INI_MH(OnUpdate_stackdriver_debugger_whitelisted_functions) +PHP_INI_MH(OnUpdate_stackdriver_debugger_allowed_functions) { /* Only use this mechanism for ini_set (runtime stage) */ if (new_value != NULL && stage & ZEND_INI_STAGE_RUNTIME) { - zend_hash_destroy(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions)); - zend_hash_init(STACKDRIVER_DEBUGGER_G(user_whitelisted_functions), 8, NULL, ZVAL_PTR_DTOR, 1); - register_user_whitelisted_functions_str(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); + zend_hash_destroy(STACKDRIVER_DEBUGGER_G(user_allowed_functions)); + zend_hash_init(STACKDRIVER_DEBUGGER_G(user_allowed_functions), 8, NULL, ZVAL_PTR_DTOR, 1); + register_user_allowed_functions_str(ZSTR_VAL(new_value), ZSTR_LEN(new_value)); } return SUCCESS; } diff --git a/stackdriver_debugger_ast.h b/stackdriver_debugger_ast.h index 2284773..ad3a34f 100644 --- a/stackdriver_debugger_ast.h +++ b/stackdriver_debugger_ast.h @@ -18,6 +18,7 @@ #define PHP_STACKDRIVER_DEBUGGER_AST_H 1 #include "php.h" +#include "stackdriver_debugger_defines.h" int valid_debugger_statement(zend_string *statement); void stackdriver_debugger_ast_process(zend_ast *ast); @@ -28,6 +29,6 @@ int stackdriver_debugger_ast_rshutdown(TSRMLS_D); void stackdriver_list_breakpoint_ids(zval *return_value); int stackdriver_debugger_breakpoint_injected(zend_string *filename, zend_string *breakpoint_id); -PHP_INI_MH(OnUpdate_stackdriver_debugger_whitelisted_functions); +PHP_INI_MH(OnUpdate_stackdriver_debugger_allowed_functions); #endif /* PHP_STACKDRIVER_DEBUGGER_AST_H */ diff --git a/stackdriver_debugger_defines.h b/stackdriver_debugger_defines.h new file mode 100644 index 0000000..a0704d7 --- /dev/null +++ b/stackdriver_debugger_defines.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PHP_STACKDRIVER_DEFINES_H +#define PHP_STACKDRIVER_DEFINES_H 1 + +#if PHP_VERSION_ID < 80000 +#define STACKDRIVER_OBJ_P(v) (v) +#else +#define STACKDRIVER_OBJ_P(v) Z_OBJ_P(v) + +#ifndef TSRMLS_D +#define TSRMLS_D void +#define TSRMLS_DC +#define TSRMLS_C +#define TSRMLS_CC +#define TSRMLS_FETCH() +#endif +#endif + +#endif diff --git a/stackdriver_debugger_logpoint.c b/stackdriver_debugger_logpoint.c index 6416e5d..90f6439 100644 --- a/stackdriver_debugger_logpoint.c +++ b/stackdriver_debugger_logpoint.c @@ -66,8 +66,13 @@ static void init_logpoint(stackdriver_debugger_logpoint_t *logpoint) /* Cleanup an allocated logpoint including freeing memory */ static void destroy_logpoint(stackdriver_debugger_logpoint_t *logpoint) { - zend_string_release(logpoint->id); - zend_string_release(logpoint->filename); + if (logpoint->id) { + zend_string_release(logpoint->id); + } + + if (logpoint->filename) { + zend_string_release(logpoint->filename); + } if (logpoint->condition) { zend_string_release(logpoint->condition); @@ -80,7 +85,7 @@ static void destroy_logpoint(stackdriver_debugger_logpoint_t *logpoint) FREE_HASHTABLE(logpoint->expressions); if (Z_TYPE(logpoint->callback) != IS_NULL) { - ZVAL_DESTRUCTOR(&logpoint->callback); + zval_ptr_dtor(&logpoint->callback); } efree(logpoint); @@ -101,7 +106,7 @@ static void destroy_message(stackdriver_debugger_message_t *message) { zend_string_release(message->filename); zend_string_release(message->log_level); - ZVAL_DESTRUCTOR(&message->message); + zval_ptr_dtor_nogc(&message->message); efree(message); } @@ -116,17 +121,17 @@ static int handle_message_callback(zval *callback, stackdriver_debugger_message_ add_assoc_str(&args[2], "filename", message->filename); add_assoc_long(&args[2], "line", message->lineno); - if (call_user_function_ex(EG(function_table), NULL, callback, &callback_result, 3, args, 0, NULL) != SUCCESS) { - ZVAL_DESTRUCTOR(&args[0]); - ZVAL_DESTRUCTOR(&args[1]); - ZVAL_DESTRUCTOR(&args[2]); - ZVAL_DESTRUCTOR(&callback_result); + if (call_user_function(EG(function_table), NULL, callback, &callback_result, 3, args) != SUCCESS) { + ZVAL_PTR_DTOR(&args[0]); + ZVAL_PTR_DTOR(&args[1]); + ZVAL_PTR_DTOR(&args[2]); + ZVAL_PTR_DTOR(&callback_result); return FAILURE; } - ZVAL_DESTRUCTOR(&args[0]); - ZVAL_DESTRUCTOR(&args[1]); - ZVAL_DESTRUCTOR(&args[2]); - ZVAL_DESTRUCTOR(&callback_result); + ZVAL_PTR_DTOR(&args[0]); + ZVAL_PTR_DTOR(&args[1]); + ZVAL_PTR_DTOR(&args[2]); + ZVAL_PTR_DTOR(&callback_result); return SUCCESS; } @@ -161,7 +166,7 @@ void evaluate_logpoint(zend_execute_data *execute_data, stackdriver_debugger_log zend_string_release(regex); m = replaced; } - ZVAL_DESTRUCTOR(&retval); + ZVAL_PTR_DTOR(&retval); } ZEND_HASH_FOREACH_END(); } ZVAL_STR(&message->message, m); diff --git a/stackdriver_debugger_logpoint.h b/stackdriver_debugger_logpoint.h index 0b07299..122cc31 100644 --- a/stackdriver_debugger_logpoint.h +++ b/stackdriver_debugger_logpoint.h @@ -18,6 +18,7 @@ #define PHP_STACKDRIVER_DEBUGGER_LOGPOINT_H 1 #include "php.h" +#include "stackdriver_debugger_defines.h" typedef struct stackdriver_debugger_logpoint_t { zend_string *id; diff --git a/stackdriver_debugger_random.h b/stackdriver_debugger_random.h index 2c6c9ab..3bda229 100644 --- a/stackdriver_debugger_random.h +++ b/stackdriver_debugger_random.h @@ -22,17 +22,18 @@ #else #include "standard/php_mt_rand.h" #endif +#include "standard/php_math.h" static zend_string *generate_breakpoint_id() { - #if PHP_VERSION_ID < 70100 - if (!BG(mt_rand_is_seeded)) { - php_mt_srand(GENERATE_SEED()); - } - #endif - - /* Force the generated id to be positive */ - return strpprintf(20, "%d", php_mt_rand() >> 1); +#if PHP_VERSION_ID < 80000 + zval zv; + ZVAL_LONG(&zv, ((uint32_t) php_mt_rand()) >> 1); + return _php_math_longtobase(&zv, 16); +#else + zend_long random_int = ((uint32_t) php_mt_rand()) >> 1; + return _php_math_longtobase(random_int, 16); +#endif } #endif /* PHP_STACKDRIVER_DEBUGGER_RANDOM_H */ diff --git a/stackdriver_debugger_snapshot.c b/stackdriver_debugger_snapshot.c index 08b0422..7c20e6b 100644 --- a/stackdriver_debugger_snapshot.c +++ b/stackdriver_debugger_snapshot.c @@ -62,7 +62,7 @@ static void destroy_stackframe(stackdriver_debugger_stackframe_t *stackframe) { int i; - if (stackframe->function && (int)stackframe->function != -1) { + if (stackframe->function) { zend_string_release(stackframe->function); } @@ -122,7 +122,7 @@ static void destroy_snapshot(stackdriver_debugger_snapshot_t *snapshot) FREE_HASHTABLE(snapshot->stackframes); if (Z_TYPE(snapshot->callback) != IS_NULL) { - ZVAL_DESTRUCTOR(&snapshot->callback); + ZVAL_PTR_DTOR(&(snapshot->callback)); } efree(snapshot); } @@ -134,6 +134,7 @@ static void destroy_snapshot(stackdriver_debugger_snapshot_t *snapshot) static void variable_to_zval(zval *return_value, stackdriver_debugger_variable_t *variable) { zend_string *hash = NULL; + array_init(return_value); add_assoc_str(return_value, "name", variable->name); add_assoc_zval(return_value, "value", &variable->value); @@ -144,11 +145,11 @@ static void variable_to_zval(zval *return_value, stackdriver_debugger_variable_t break; case IS_ARRAY: /* Use the memory address of the zend_array */ - hash = strpprintf(16, "%016zx", Z_ARR(variable->value)); + hash = strpprintf(16, "%016zx", (size_t)Z_ARR(variable->value)); break; case IS_STRING: /* Use the internal HashTable value */ - hash = strpprintf(32, "%016zx", ZSTR_HASH(Z_STR(variable->value))); + hash = strpprintf(32, "%016zx", Z_STRHASH(variable->value)); break; } if (hash != NULL) { @@ -438,10 +439,10 @@ static int handle_snapshot_callback(zval *callback, stackdriver_debugger_snapsho { zval zsnapshot, callback_result; snapshot_to_zval(&zsnapshot, snapshot); - int call_result = call_user_function_ex(EG(function_table), NULL, callback, &callback_result, 1, &zsnapshot, 0, NULL); + int call_result = call_user_function(EG(function_table), NULL, callback, &callback_result, 1, &zsnapshot); - ZVAL_DESTRUCTOR(&zsnapshot); - ZVAL_DESTRUCTOR(&callback_result); + zval_ptr_dtor_nogc(&zsnapshot); + zval_ptr_dtor_nogc(&callback_result); return call_result; } diff --git a/stackdriver_debugger_snapshot.h b/stackdriver_debugger_snapshot.h index e7c5c1a..95d72d6 100644 --- a/stackdriver_debugger_snapshot.h +++ b/stackdriver_debugger_snapshot.h @@ -18,6 +18,8 @@ #define PHP_STACKDRIVER_DEBUGGER_SNAPSHOT_H 1 #include "php.h" +#include "stackdriver_debugger_defines.h" + typedef struct stackdriver_debugger_variable_t { zend_string *name; diff --git a/testapps/composer.json b/testapps/composer.json index 9eb382e..b1bf49f 100644 --- a/testapps/composer.json +++ b/testapps/composer.json @@ -6,7 +6,7 @@ "google/cloud": "~0.54" }, "require-dev": { - "phpunit/phpunit": "6.0.*", + "phpunit/phpunit": "7 || 8 || ^9.5", "squizlabs/php_codesniffer": "2.*", "fabpot/goutte": "^3.2" } diff --git a/testapps/phpunit.xml.dist b/testapps/phpunit.xml.dist index 7eb6797..e62e2c1 100644 --- a/testapps/phpunit.xml.dist +++ b/testapps/phpunit.xml.dist @@ -1,7 +1,7 @@ - + tests/functional diff --git a/testapps/tests/functional/AppTest.php b/testapps/tests/functional/AppTest.php index 56e1ce6..e8c3bc6 100644 --- a/testapps/tests/functional/AppTest.php +++ b/testapps/tests/functional/AppTest.php @@ -28,21 +28,21 @@ class AppTest extends TestCase private $client; - public static function setupBeforeClass() + public static function setupBeforeClass(): void { $client = new DebuggerClient(); self::$debuggee = $client->debuggee('debuggeeid'); self::$storage = new FileBreakpointStorage(); } - public function setUp() + public function setUp(): void { // clear any breakpoints $this->clearBreakpoints(); $this->client = new Client(); } - public function tearDown() + public function tearDown(): void { $this->clearBreakpoints(); } @@ -65,7 +65,7 @@ public function testAddsLogpoint() // no logpoints should be set, so no logpoint is found $this->fetchPath('/hello/jeff'); $content = $this->client->getResponse()->getContent(); - $this->assertNotContains('[INFO] LOGPOINT: hello there', $content); + $this->assertStringNotContainsString('[INFO] LOGPOINT: hello there', $content); // add a logpoint $this->addBreakpoint('logpoint1', 'web/index.php', 34, [ @@ -77,7 +77,7 @@ public function testAddsLogpoint() for ($i = 0; $i < 5; $i++) { $this->fetchPath('/hello/jeff'); $content = $this->client->getResponse()->getContent(); - $this->assertContains('[INFO] LOGPOINT: hello there', $content); + $this->assertStringNotContainsString('[INFO] LOGPOINT: hello there', $content); } // remove the breakpoint @@ -86,7 +86,7 @@ public function testAddsLogpoint() // no logpoints should be set any more $this->fetchPath('/hello/jeff'); $content = $this->client->getResponse()->getContent(); - $this->assertNotContains('[INFO] LOGPOINT: hello there', $content); + $this->assertStringNotContainsString('[INFO] LOGPOINT: hello there', $content); } private function fetchPath($path, $method = 'GET') diff --git a/tests/function_whitelist.phpt b/tests/function_allowed.phpt similarity index 72% rename from tests/function_whitelist.phpt rename to tests/function_allowed.phpt index 3b19678..49fd754 100644 --- a/tests/function_whitelist.phpt +++ b/tests/function_allowed.phpt @@ -1,7 +1,7 @@ --TEST-- -Stackdriver Debugger: Allowing a whitelisted function +Stackdriver Debugger: Allowing a function to be used --INI-- -stackdriver_debugger.function_whitelist="foo" +stackdriver_debugger.functions_allowed="foo" --FILE-- --EXPECTF-- bool(true) @@ -33,6 +35,7 @@ Number of breakpoints: 1 Number of stackframes: 2 loop.php:7 basic_variable_dump.php:8 +predump array(4) { [0]=> array(2) { @@ -63,3 +66,4 @@ array(4) { NULL } } +postdump diff --git a/tests/snapshots/conditional_warning.phpt b/tests/snapshots/conditional_warning.phpt index 378bc69..8a06c38 100644 --- a/tests/snapshots/conditional_warning.phpt +++ b/tests/snapshots/conditional_warning.phpt @@ -19,5 +19,5 @@ echo "Number of breakpoints: " . count($list) . PHP_EOL; --EXPECTF-- bool(true) -Notice: %s in conditional on line 1 +%s: %s in conditional on line 1 Number of breakpoints: 0 diff --git a/tests/snapshots/expressions_warning.phpt b/tests/snapshots/expressions_warning.phpt index 2e3fd9b..abce758 100644 --- a/tests/snapshots/expressions_warning.phpt +++ b/tests/snapshots/expressions_warning.phpt @@ -21,5 +21,5 @@ echo "Number of breakpoints: " . count($list) . PHP_EOL; --EXPECTF-- bool(true) -Notice: %s in expression evaluation on line 1 +%s: %s in expression evaluation on line 1 Number of breakpoints: 1 diff --git a/tests/statement_validity.phpt b/tests/statement_validity.phpt index 7c81701..9dc6725 100644 --- a/tests/statement_validity.phpt +++ b/tests/statement_validity.phpt @@ -17,8 +17,8 @@ $statements = [ 'false;', '$times == 4', // syntax errors - 'asdf->foo;', - // whitelisted function + '->foo;', + // allowed function 'count(array([])) == 0', 'count([]) == 0', 'count(array_keys([])) == 0', @@ -44,7 +44,7 @@ statement: 'foo($bar);' valid: false statement: 'true;' valid: true statement: 'false;' valid: true statement: '$times == 4' valid: true -statement: 'asdf->foo;' valid: false +statement: '->foo;' valid: false statement: 'count(array([])) == 0' valid: true statement: 'count([]) == 0' valid: true statement: 'count(array_keys([])) == 0' valid: true