コード例 #1
0
ファイル: PDO.Attribute.cs プロジェクト: tyty999/peachpie
        public virtual bool setAttribute(PDO_ATTR attribute, PhpValue value)
        {
            long l; // temp value

            switch (attribute)
            {
            //readonly
            case PDO_ATTR.ATTR_SERVER_INFO:
            case PDO_ATTR.ATTR_SERVER_VERSION:
            case PDO_ATTR.ATTR_CLIENT_VERSION:
            case PDO_ATTR.ATTR_CONNECTION_STATUS:
            case PDO_ATTR.ATTR_DRIVER_NAME:
                return(false);

            //boolean

            case PDO_ATTR.ATTR_AUTOCOMMIT:
            case PDO_ATTR.ATTR_EMULATE_PREPARES:
                GetOrCreateAttributes()[attribute] = value.ToBoolean();
                return(true);

            case PDO_ATTR.ATTR_STRINGIFY_FETCHES:
                Driver.TrySetStringifyFetches(this, value.ToBoolean());
                return(true);    // always returns TRUE

            //strict positif integers

            case PDO_ATTR.ATTR_PREFETCH:
            case PDO_ATTR.ATTR_TIMEOUT:
                // TODO: strict positif integers
                GetOrCreateAttributes()[attribute] = value.GetValue().DeepCopy();
                return(true);

            //remaining

            case PDO_ATTR.ATTR_ERRMODE:
                l = value.ToLong();
                if (Enum.IsDefined(typeof(PDO_ERRMODE), (int)l))
                {
                    GetOrCreateAttributes()[attribute] = l;
                    return(true);
                }
                else
                {
                    // Warning: PDO::setAttribute(): SQLSTATE[HY000]: General error: invalid error mode
                    // TODO: this.RaiseError( ... ) ?
                    PhpException.InvalidArgument(nameof(value));
                    return(false);
                }

            case PDO_ATTR.ATTR_CASE:
                l = value.ToLong();
                if (Enum.IsDefined(typeof(PDO_CASE), (int)l))
                {
                    GetOrCreateAttributes()[attribute] = l;
                    return(true);
                }
                return(false);

            case PDO_ATTR.ATTR_CURSOR:
                l = value.ToLong();
                if (Enum.IsDefined(typeof(PDO_CURSOR), (int)l))
                {
                    GetOrCreateAttributes()[attribute] = l;
                    return(true);
                }
                return(false);

            case PDO_ATTR.ATTR_DEFAULT_FETCH_MODE:
                l = value.ToLong();
                if (Enum.IsDefined(typeof(PDO_FETCH), (int)l))
                {
                    GetOrCreateAttributes()[attribute] = l;
                    return(true);
                }
                return(false);

            case PDO_ATTR.ATTR_STATEMENT_CLASS:
                if (value.IsPhpArray(out var arr) && arr != null && arr.Count != 0)
                {
                    GetOrCreateAttributes()[attribute] = arr.DeepCopy();
                    return(true);
                }
                return(false);

            case PDO_ATTR.ATTR_ORACLE_NULLS:
                if (value.IsLong(out l))
                {
                    Debug.Assert(l == (long)PDO_NULL.NULL_NATURAL, "nonstandard ATTR_ORACLE_NULLS is not yet supported");
                    _oracle_nulls = (PDO_NULL)l;
                    return(true);
                }
                else
                {
                    HandleError("attribute value must be an integer");
                    return(false);
                }

            case PDO_ATTR.ATTR_FETCH_CATALOG_NAMES:
            case PDO_ATTR.ATTR_FETCH_TABLE_NAMES:
            case PDO_ATTR.ATTR_MAX_COLUMN_LEN:
            case PDO_ATTR.ATTR_PERSISTENT:
                throw new NotImplementedException($"setAttribute({attribute})");

            //statement only
            case PDO_ATTR.ATTR_CURSOR_NAME:
                return(false);

            default:

                // driver specific
                try
                {
                    if (attribute >= PDO_ATTR.ATTR_DRIVER_SPECIFIC)
                    {
                        return(Driver.TrySetAttribute(GetOrCreateAttributes(), (int)attribute, value));
                    }
                }
                catch (System.Exception ex)
                {
                    this.HandleError(ex);
                    return(false);
                }

                // invalid attribute:
                Debug.WriteLine($"PDO_ATTR {attribute} is not known.");
                return(false);
            }
        }
コード例 #2
0
        /// <summary>
        /// Filters a variable with a specified filter.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="variable">Value to filter.</param>
        /// <param name="filter">The ID of the filter to apply.</param>
        /// <param name="options">Associative array of options or bitwise disjunction of flags. If filter accepts options, flags can be provided in "flags" field of array. For the "callback" filter, callback type should be passed. The callback must accept one argument, the value to be filtered, and return the value after filtering/sanitizing it.</param>
        /// <returns>Returns the filtered data, or <c>false</c> if the filter fails.</returns>
        public static PhpValue filter_var(Context ctx, PhpValue variable, int filter = FILTER_DEFAULT, PhpValue options = default(PhpValue))
        {
            var      @default    = PhpValue.False; // a default value
            PhpArray options_arr = null;
            long     flags       = 0;

            // process options

            if (options.IsSet)
            {
                options_arr = options.AsArray();
                if (options_arr != null)
                {
                    // [flags]
                    if (options_arr.TryGetValue("flags", out var flagsval))
                    {
                        flagsval.IsLong(out flags);
                    }

                    // [default]
                    if (options_arr.TryGetValue("default", out var defaultval))
                    {
                        @default = defaultval;
                    }

                    // ...
                }
                else
                {
                    options.IsLong(out flags);
                }
            }

            switch (filter)
            {
            //
            // SANITIZE
            //

            case (int)FilterSanitize.FILTER_DEFAULT:
                return((PhpValue)variable.ToString(ctx));

            case (int)FilterSanitize.EMAIL:
                // Remove all characters except letters, digits and !#$%&'*+-/=?^_`{|}~@.[].
                return((PhpValue)FilterSanitizeString(variable.ToString(ctx), (c) =>
                                                      (int)c <= 0x7f && (Char.IsLetterOrDigit(c) ||
                                                                         c == '!' || c == '#' || c == '$' || c == '%' || c == '&' || c == '\'' ||
                                                                         c == '*' || c == '+' || c == '-' || c == '/' || c == '=' || c == '!' ||
                                                                         c == '?' || c == '^' || c == '_' || c == '`' || c == '{' || c == '|' ||
                                                                         c == '}' || c == '~' || c == '@' || c == '.' || c == '[' || c == ']')));

            //
            // VALIDATE
            //

            case (int)FilterValidate.URL:
                return(Uri.TryCreate(variable.ToString(ctx), UriKind.Absolute, out var uri)
                        ? (PhpValue)uri.AbsoluteUri
                        : PhpValue.False);

            case (int)FilterValidate.EMAIL:
            {
                var str = variable.ToString(ctx);
                return(RegexUtilities.IsValidEmail(str)
                            ? (PhpValue)str
                            : PhpValue.False);
            }

            case (int)FilterValidate.INT:
            {
                int result;
                if (int.TryParse((PhpVariable.AsString(variable) ?? string.Empty).Trim(), out result))
                {
                    if (Operators.IsSet(options))
                    {
                        PhpException.ArgumentValueNotSupported("options", "!null");
                    }

                    return((PhpValue)result);         // TODO: options: min_range, max_range
                }
                else
                {
                    return(@default);
                }
            }

            case (int)FilterValidate.BOOLEAN:
            {
                if (variable.IsBoolean(out var b))
                {
                    return(b);
                }

                var varstr = variable.ToString(ctx);

                // TRUE for "1", "true", "on" and "yes".

                if (varstr.EqualsOrdinalIgnoreCase("1") ||
                    varstr.EqualsOrdinalIgnoreCase("true") ||
                    varstr.EqualsOrdinalIgnoreCase("on") ||
                    varstr.EqualsOrdinalIgnoreCase("yes"))
                {
                    return(PhpValue.True);
                }

                //
                if ((flags & FILTER_NULL_ON_FAILURE) == FILTER_NULL_ON_FAILURE)
                {
                    // FALSE is for "0", "false", "off", "no", and "",
                    // NULL for all non-boolean values

                    if (varstr.Length == 0 ||
                        varstr.EqualsOrdinalIgnoreCase("0") ||
                        varstr.EqualsOrdinalIgnoreCase("false") ||
                        varstr.EqualsOrdinalIgnoreCase("off"))
                    {
                        return(PhpValue.False);
                    }
                    else
                    {
                        return(PhpValue.Null);
                    }
                }
                else
                {
                    // FALSE otherwise
                    return(PhpValue.False);
                }
            }

            case (int)FilterValidate.REGEXP:
            {
                // options = options['regexp']
                if (options_arr != null &&
                    options_arr.TryGetValue("regexp", out var regexpval))
                {
                    if (PCRE.preg_match(ctx, regexpval.ToString(ctx), variable.ToString(ctx)) > 0)
                    {
                        return(variable);
                    }
                }
                else
                {
                    PhpException.InvalidArgument("options", string.Format(Resources.LibResources.option_missing, "regexp"));
                }

                return(PhpValue.False);
            }

            default:
                PhpException.ArgumentValueNotSupported(nameof(filter), filter);
                break;
            }

            return(PhpValue.False);
        }
コード例 #3
0
        /// <summary>
        /// Filters a variable with a specified filter.
        /// </summary>
        /// <param name="ctx">Runtime context.</param>
        /// <param name="variable">Value to filter.</param>
        /// <param name="filter">The ID of the filter to apply.</param>
        /// <param name="options">Associative array of options or bitwise disjunction of flags. If filter accepts options, flags can be provided in "flags" field of array. For the "callback" filter, callback type should be passed. The callback must accept one argument, the value to be filtered, and return the value after filtering/sanitizing it.</param>
        /// <returns>Returns the filtered data, or <c>false</c> if the filter fails.</returns>
        public static PhpValue filter_var(Context ctx, PhpValue variable, int filter = FILTER_DEFAULT, PhpValue options = default(PhpValue))
        {
            var      @default    = PhpValue.False; // a default value
            PhpArray options_arr = null;
            long     flags       = 0;

            // process options

            if (Operators.IsSet(options))
            {
                options_arr = options.AsArray();
                if (options_arr != null)
                {
                    // [flags]
                    if (options_arr.TryGetValue("flags", out var flagsval))
                    {
                        flagsval.IsLong(out flags);
                    }

                    // [options] => { "min_range" => ??, "default" => ?? }
                    if (options_arr.TryGetValue("options", out var optionsval) && optionsval.IsPhpArray(out var opts_arr))
                    {
                        // [default]
                        if (opts_arr.TryGetValue("default", out var defaultval))
                        {
                            @default = defaultval;
                        }
                    }
                }
                else
                {
                    options.IsLong(out flags);
                }
            }

            switch (filter)
            {
            //
            // SANITIZE
            //

            case (int)FilterSanitize.FILTER_DEFAULT:
                return((PhpValue)variable.ToString(ctx));

            case (int)FilterSanitize.EMAIL:
                // Remove all characters except letters, digits and !#$%&'*+-/=?^_`{|}~@.[].
                return((PhpValue)FilterSanitizeString(variable.ToString(ctx), (c) =>
                                                      (int)c <= 0x7f && (Char.IsLetterOrDigit(c) ||
                                                                         c == '!' || c == '#' || c == '$' || c == '%' || c == '&' || c == '\'' ||
                                                                         c == '*' || c == '+' || c == '-' || c == '/' || c == '=' || c == '!' ||
                                                                         c == '?' || c == '^' || c == '_' || c == '`' || c == '{' || c == '|' ||
                                                                         c == '}' || c == '~' || c == '@' || c == '.' || c == '[' || c == ']')));

            //
            // VALIDATE
            //

            case (int)FilterValidate.URL:

                // TODO: protocol may be ommited, try to add "http://" if fails

                if (Uri.TryCreate(variable.ToString(ctx), UriKind.Absolute, out var uri))
                {
                    if (uri.IsFile && !uri.OriginalString.StartsWith(uri.Scheme, StringComparison.OrdinalIgnoreCase))
                    {
                        // quick check the file:// was just added on linux impl. of Uri.Parse
                        return(@default);
                    }

                    if (flags != 0)
                    {
                        // CONSIDER: rather use `Web.parse_url()` ...
                        var uriflags = (FilterFlag)flags;
                        //if ((uriflags & FilterFlag.PATH_REQUIRED) == FilterFlag.PATH_REQUIRED && ...)
                    }

                    return(uri.AbsoluteUri);
                }
                return(@default);

            case (int)FilterValidate.EMAIL:
            {
                return(variable.IsString(out var str) && RegexUtilities.IsValidEmail(str)
                            ? (PhpValue)str
                            : @default);
            }

            case (int)FilterValidate.IP:
                if (System.Net.IPAddress.TryParse(variable.ToString(ctx), out var addr))
                {
                    if (flags != 0)
                    {
                        // validate flags:
                        if ((addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6 && (flags & (int)FilterFlag.IPV6) == 0) ||
                            (addr.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork && (flags & (int)FilterFlag.IPV4) == 0))
                        {
                            return(@default);
                        }

                        if ((flags & (int)FilterFlag.NO_PRIV_RANGE) == (int)FilterFlag.NO_PRIV_RANGE)
                        {
                            /*
                             * Fails validation for the IPv4 ranges: 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.
                             * Fails validation for the IPv6 addresses starting with FD or FC.
                             */
                            throw new NotImplementedException();
                        }

                        if ((flags & (int)FilterFlag.NO_PRIV_RANGE) == (int)FilterFlag.NO_RES_RANGE)
                        {
                            /*
                             * Fails validation for IPv4 ranges: 0.0.0.0/8, 169.254.0.0/16, 127.0.0.0/8 and 240.0.0.0/4.
                             * Fails validation for IPv6 ranges: ::1/128, ::/128, ::ffff:0:0/96 and fe80::/10.
                             */
                            throw new NotImplementedException();
                        }
                    }

                    return(addr.ToString());
                }
                else
                {
                    return(@default);
                }

            case (int)FilterValidate.INT:
            {
                int result;
                if (int.TryParse((PhpVariable.AsString(variable) ?? string.Empty).Trim(), out result))
                {
                    if (Operators.IsSet(options))
                    {
                        PhpException.ArgumentValueNotSupported("options", "!null");
                    }

                    return((PhpValue)result);         // TODO: options: min_range, max_range
                }
                else
                {
                    return(@default);
                }
            }

            case (int)FilterValidate.BOOLEAN:
            {
                if (variable.IsBoolean(out var b))
                {
                    return(b);
                }

                var varstr = variable.ToString(ctx);

                // TRUE for "1", "true", "on" and "yes".

                if (varstr.EqualsOrdinalIgnoreCase("1") ||
                    varstr.EqualsOrdinalIgnoreCase("true") ||
                    varstr.EqualsOrdinalIgnoreCase("on") ||
                    varstr.EqualsOrdinalIgnoreCase("yes"))
                {
                    return(PhpValue.True);
                }

                //
                if ((flags & FILTER_NULL_ON_FAILURE) == FILTER_NULL_ON_FAILURE)
                {
                    // FALSE is for "0", "false", "off", "no", and "",
                    // NULL for all non-boolean values

                    if (varstr.Length == 0 ||
                        varstr.EqualsOrdinalIgnoreCase("0") ||
                        varstr.EqualsOrdinalIgnoreCase("false") ||
                        varstr.EqualsOrdinalIgnoreCase("off"))
                    {
                        return(PhpValue.False);
                    }
                    else
                    {
                        return(PhpValue.Null);
                    }
                }
                else
                {
                    // FALSE otherwise
                    return(PhpValue.False);
                }
            }

            case (int)FilterValidate.REGEXP:
            {
                // options = options['regexp']
                if (options_arr != null &&
                    options_arr.TryGetValue("regexp", out var regexpval))
                {
                    if (PCRE.preg_match(ctx, regexpval.ToString(ctx), variable.ToString(ctx)) > 0)
                    {
                        return(variable);
                    }
                }
                else
                {
                    PhpException.InvalidArgument("options", string.Format(Resources.LibResources.option_missing, "regexp"));
                }

                return(@default);
            }

            case FILTER_CALLBACK:
                // options = ['options' => $callback]
                if (options_arr != null &&
                    options_arr.TryGetValue("options", out var callbackvar))
                {
                    return(callbackvar.AsCallable().Invoke(ctx, variable));
                }

                return(@default);

            default:
                PhpException.ArgumentValueNotSupported(nameof(filter), filter);
                break;
            }

            return(PhpValue.False);
        }