/// <summary> /// Adds slashes before characters '\\', '\0', '\'' and '"'. /// </summary> /// <param name="str">The string to add slashes in.</param> /// <param name="doubleQuotes">Whether to slash double quotes.</param> /// <param name="singleQuotes">Whether to slash single quotes.</param> /// <param name="nul">Whether to slash '\0' character.</param> /// <returns>The slashed string.</returns> /// <exception cref="ArgumentNullException"><paramref name="str"/> is a <B>null</B> reference.</exception> public static string /*!*/ AddCSlashes(string /*!*/ str, bool singleQuotes = true, bool doubleQuotes = true, bool nul = true) { if (str == null) { throw new ArgumentNullException(nameof(str)); } var result = StringBuilderUtilities.Pool.Get(); string double_quotes = doubleQuotes ? "\\\"" : "\""; string single_quotes = singleQuotes ? @"\'" : "'"; string slashed_nul = nul ? "\\0" : "\0"; for (int i = 0; i < str.Length; i++) { char c = str[i]; switch (c) { case '\\': result.Append(@"\\"); break; case '\0': result.Append(slashed_nul); break; case '\'': result.Append(single_quotes); break; case '"': result.Append(double_quotes); break; default: result.Append(c); break; } } return(StringBuilderUtilities.GetStringAndReturn(result)); }
private static string /*!*/ Unescape(string /*!*/ path, int start) { var unescaped = StringBuilderUtilities.Pool.Get(); var inEscape = false; for (int i = start; i < path.Length; i++) { var c = path[i]; if (inEscape) { inEscape = false; } else if (c == '\\') { inEscape = true; continue; } unescaped.Append(c); } if (inEscape) { unescaped.Append('\\'); } // return(StringBuilderUtilities.GetStringAndReturn(unescaped)); }
public static string Serialize(Context ctx, PhpValue variable, JsonEncodeOptions encodeOptions, RuntimeTypeHandle caller) { var str = StringBuilderUtilities.Pool.Get(); variable.Accept(new ObjectWriter(ctx, str, encodeOptions, caller)); return(StringBuilderUtilities.GetStringAndReturn(str)); // note: str is cleared }
public bool Parse(string input, bool isFinal) { // the problem is when isFinal == false // XmlReader (more precisely XmlTextReaderImpl) synchronously waits for data from underlying stream when Read is called // and there is no way to tell whether we have sufficient amount of data for the next Read call // and if underlying stream ends prematurely, reader will get into Error state (so these simple workarounds are not possible) // current solution caches the data until isFinal == true and then performs the parsing // this is not memory efficient (usually this method gets called in a cycle on small chunks to save memory) // other way would be to let the reader wait on another thread (in thread pool), which would not be that bad // since XmlParser gets freed eventually // theoretically the best way would be to implement XmlReader, that would be able to recognize whether there is enough // data, but we have not further analyzed this possibility since it seems to result in unappropriate amount of work // yet another possible way is to use parser for inner element, and let it come into error state (not tested or thought through) // this does not work since inner parser can only be created when the parser reads an element (not in the beginning) if (isFinal) { input ??= string.Empty; var sb = StringBuilderUtilities.Pool.Get(); if (_inputQueue != null) { foreach (string s in _inputQueue) { sb.Append(s); } _inputQueue = null; } sb.Append(input); return(ParseInternal(StringBuilderUtilities.GetStringAndReturn(sb), null, null)); } else { //just reset these values - we are still in the beginning CurrentLineNumber = 0; CurrentColumnNumber = 0; if (!string.IsNullOrEmpty(input)) { if (_inputQueue == null) { _inputQueue = new Queue <string>(); } _inputQueue.Enqueue(input); } return(true); } }
static string ToString(Rational num, int scale) { var numerator = BigInteger.Abs(num.Numerator); var denominator = BigInteger.Abs(num.Denominator); var hasdecimal = false; var result = StringBuilderUtilities.Pool.Get(); if (num.Sign < 0) { result.Append('-'); } for (; ;) { var number = BigInteger.DivRem(numerator, denominator, out var rem); if (number >= 10) { var digits = number.ToString(NumberFormatInfo.InvariantInfo); result.Append(digits); } else { Debug.Assert(number >= 0); result.Append((char)('0' + (int)number)); } if (scale <= 0) { break; } // . if (!hasdecimal) { hasdecimal = true; result.Append(NumberFormatInfo.InvariantInfo.NumberDecimalSeparator); } // done? if (rem.IsZero) { result.Append('0', scale); break; } // next decimals numerator = rem * 10; scale--; } // return(StringBuilderUtilities.GetStringAndReturn(result)); }
/// <summary> /// Gets stack trace as string. /// </summary> public static string GetStackTraceString(this PhpStackTrace trace, int skip = 0) { var result = StringBuilderUtilities.Pool.Get(); var lines = trace.GetLines(); for (int i = 1 + skip, order = 0; i < lines.Length; i++, order++) { lines[i].GetStackTraceLine(order, result); result.AppendLine(); } return(StringBuilderUtilities.GetStringAndReturn(result)); }
/// <summary> /// Strips slashes from a string. /// </summary> /// <param name="str">String.</param> /// <returns> /// String where slashes are striped away. /// Slashed characters with special meaning ("\0") are replaced with their special value. /// </returns> public static string /*!*/ StripCSlashes(string /*!*/ str) { if (str == null) { throw new ArgumentNullException(nameof(str)); } if (str.Length == 0) { return(string.Empty); } var result = StringBuilderUtilities.Pool.Get(); int from = 0; // plain chunk start for (int i = 0; i < str.Length; i++) { if (str[i] == '\\') { // result.Append(str, from, i - from); // if (++i < str.Length) { // PHP strips all slashes, not only quotes and slash // "\0" has a special meaning => '\0' var slashed = str[i]; result.Append(slashed == '0' ? '\0' : slashed); } from = i + 1; } } // if (from < str.Length) { result.Append(str, from, str.Length - from); } // return(StringBuilderUtilities.GetStringAndReturn(result)); }
/// <summary> /// Quote regular expression characters. /// </summary> /// <remarks> /// The special regular expression characters are: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : - /// Note that / is not a special regular expression character. /// </remarks> /// <param name="str">The string to be escaped.</param> /// <param name="delimiter">If the optional delimiter is specified, it will also be escaped. /// This is useful for escaping the delimiter that is required by the PCRE functions. The / is the most commonly used delimiter.</param> public static string preg_quote(string str, string delimiter = null) { if (string.IsNullOrEmpty(str)) { return(str); } char delimiterChar = string.IsNullOrEmpty(delimiter) ? char.MaxValue // unused (?) : delimiter[0]; StringBuilder result = null; int lastEscape = 0; for (int i = 0; i < str.Length; i++) { char ch = str[i]; bool escape = ch == delimiterChar || IsDelimiterChar(ch); if (escape) { if (result == null) { result = StringBuilderUtilities.Pool.Get(); } result.Append(str, lastEscape, i - lastEscape); result.Append('\\'); lastEscape = i; } } if (result != null) { result.Append(str, lastEscape, str.Length - lastEscape); return(StringBuilderUtilities.GetStringAndReturn(result)); } else { return(str); } }
/// <summary> /// Gets exception string. /// </summary> public static string FormatExceptionString(this PhpStackTrace trace, string exceptionname, string message) { var result = StringBuilderUtilities.Pool.Get(); // TODO: texts to resources // {exceptionname} in {location} // Stack trace: // #0 ... var lines = trace.GetLines(); result.Append(exceptionname); if (!string.IsNullOrEmpty(message)) { result.Append(": "); result.Append(message); } if (lines.Length != 0) { if (lines[0].HasLocation) { result.Append(" in "); lines[0].GetStackTraceLine(-1, result); } if (lines.Length > 1) { result.AppendLine(); result.AppendLine("Stack trace:"); for (int i = 1; i < lines.Length; i++) { lines[i].GetStackTraceLine(i - 1, result); result.AppendLine(); } } } // return(StringBuilderUtilities.GetStringAndReturn(result)); }
/// <summary> /// Replaces slashed 0 with null character ('\0') and double apostrophe with single apostrophe. /// </summary> /// <param name="str">String.</param> /// <returns>String with replaced characters.</returns> public static string /*!*/ StripDbSlashes(string /*!*/ str) { if (str == null) { throw new ArgumentNullException(nameof(str)); } var result = StringBuilderUtilities.Pool.Get(); int i = 0; while (i < str.Length - 1) { if (str[i] == '\\' && str[i + 1] == '0') { result.Append('\0'); i += 2; } else if (str[i] == '\'' && str[i + 1] == '\'') { result.Append('\''); i += 2; } else { result.Append(str[i]); i++; } } if (i < str.Length) { result.Append(str[i]); } return(StringBuilderUtilities.GetStringAndReturn(result)); }
/// <summary> /// Adds slash before '\0' character and duplicates apostrophes. /// </summary> /// <param name="str">The string to add slashes in.</param> /// <returns>The slashed string.</returns> /// <exception cref="ArgumentNullException"><paramref name="str"/> is a <B>null</B> reference.</exception> public static string /*!*/ AddDbSlashes(string /*!*/ str) { if (str == null) { throw new ArgumentNullException(nameof(str)); } StringBuilder result = StringBuilderUtilities.Pool.Get(); for (int i = 0; i < str.Length; i++) { char c = str[i]; switch (c) { case '\0': result.Append('\\'); result.Append('0'); break; case '\'': result.Append('\''); result.Append('\''); break; default: result.Append(c); break; } } return(StringBuilderUtilities.GetStringAndReturn(result)); }
private static string DoubleToBase(double number, int toBase) { if (toBase < 2 || toBase > 36) { PhpException.InvalidArgument(nameof(toBase), Resources.LibResources.arg_out_of_bounds); return(null); // FALSE } // Don't try to convert infinity or NaN: if (double.IsInfinity(number) || double.IsNaN(number)) { PhpException.InvalidArgument(nameof(number), Resources.LibResources.arg_out_of_bounds); return(null); // FALSE } double fvalue = Math.Floor(number); /* floor it just in case */ if (Math.Abs(fvalue) < 1) { return("0"); } var sb = StringBuilderUtilities.Pool.Get(); while (Math.Abs(fvalue) >= 1) { double mod = fmod(fvalue, toBase); int i = (int)mod; char c = digitsUnicode[i]; //sb.Append(digits[(int) fmod(fvalue, toBase)]); sb.Append(c); fvalue /= toBase; } return(Core.Utilities.StringUtils.Reverse(StringBuilderUtilities.GetStringAndReturn(sb))); }
/// <summary> /// Unpacks data from a string of bytes into <see cref="PhpArray"/>. /// </summary> /// <param name="ctx">Runtime context.</param> /// <param name="format">The string defining the items of the result. See PHP manual for details.</param> /// <param name="data">The string of bytes to be unpacked.</param> /// <returns>The <see cref="PhpArray"/> containing unpacked data.</returns> public static PhpArray unpack(Context ctx, string format, PhpString data) { if (format == null) { return(null); } byte[] buffer = data.ToBytes(ctx); var encoding = ctx.StringEncoding; byte[] reversed = new byte[4]; // used for reversing the order of bytes in buffer int i = 0; int pos = 0; PhpArray result = new PhpArray(); while (i < format.Length) { string name; int repeater; char specifier; // parses specifier, repeater, and name from the format string: ParseFormatToken(format, ref i, out specifier, out repeater, out name); int remains = buffer.Length - pos; // the number of bytes remaining in the buffer int size; // a size of data to be extracted corresponding to the specifier // repeater of '@' specifier has a special meaning: if (specifier == '@') { if (repeater > buffer.Length || repeater == InfiniteRepeater) { PhpException.Throw(PhpError.Warning, LibResources.GetString("outside_string", specifier)); } else { pos = repeater; } continue; } // number of operations: int op_count; // gets the size of the data to read and adjust repeater: if (!GetSizeToUnpack(specifier, remains, repeater, out op_count, out size)) { PhpException.Throw(PhpError.Warning, LibResources.GetString("unknown_format_code", specifier)); return(null); } // repeats operation determined by specifier "op_count" times; // if op_count is infinite then stops when the number of remaining characters is zero: for (int j = 0; j < op_count || op_count == InfiniteRepeater; j++) { if (size > remains) { // infinite means "while data are available": if (op_count == InfiniteRepeater) { break; } PhpException.Throw(PhpError.Warning, LibResources.GetString("not_enought_input", specifier, size, remains)); return(null); } PhpValue item; switch (specifier) { case 'X': // decreases position, no value stored: if (pos == 0) { PhpException.Throw(PhpError.Warning, LibResources.GetString("outside_string", specifier)); } else { pos--; } continue; case 'x': // advances position, no value stored pos++; continue; case 'a': // NUL-padded string case 'A': // SPACE-padded string { byte pad = (byte)(specifier == 'a' ? 0x00 : 0x20); int last = pos + size - 1; while (last >= pos && buffer[last] == pad) { last--; } item = (PhpValue)encoding.GetString(buffer, pos, last - pos + 1); break; } case 'h': // Hex string, low/high nibble first - converts to a string, takes n hex digits from string: case 'H': { int p = pos; int nibble_shift = (specifier == 'h') ? 0 : 4; var sb = StringBuilderUtilities.Pool.Get(); for (int k = 0; k < size; k++) { const string hex_digits = "0123456789ABCDEF"; sb.Append(hex_digits[(buffer[p] >> nibble_shift) & 0x0f]); // beware of odd repeaters! if (repeater == InfiniteRepeater || repeater > sb.Length) { sb.Append(hex_digits[(buffer[p] >> (4 - nibble_shift)) & 0x0f]); } p++; } item = StringBuilderUtilities.GetStringAndReturn(sb); break; } case 'c': // signed char item = (PhpValue)(int)unchecked ((sbyte)buffer[pos]); break; case 'C': // unsigned char item = (PhpValue)(int)buffer[pos]; break; case 's': // signed short (always 16 bit, machine byte order) item = (PhpValue)(int)BitConverter.ToInt16(buffer, pos); break; case 'S': // unsigned short (always 16 bit, machine byte order) item = (PhpValue)(int)BitConverter.ToUInt16(buffer, pos); break; case 'n': // unsigned short (always 16 bit, big endian byte order) if (BitConverter.IsLittleEndian) { item = (PhpValue)(int)BitConverter.ToUInt16(LoadReverseBuffer(reversed, buffer, pos, 2), 0); } else { item = (PhpValue)(int)BitConverter.ToUInt16(buffer, pos); } break; case 'v': // unsigned short (always 16 bit, little endian byte order) if (!BitConverter.IsLittleEndian) { item = (PhpValue)(int)BitConverter.ToUInt16(LoadReverseBuffer(reversed, buffer, pos, 2), 0); } else { item = (PhpValue)(int)BitConverter.ToUInt16(buffer, pos); } break; case 'i': // signed integer (machine dependent size and byte order - always 32 bit) case 'I': // unsigned integer (machine dependent size and byte order - always 32 bit) case 'l': // signed long (always 32 bit, machine byte order) case 'L': // unsigned long (always 32 bit, machine byte order) item = (PhpValue)BitConverter.ToInt32(buffer, pos); break; case 'N': // unsigned long (always 32 bit, big endian byte order) item = (PhpValue) unchecked (((int)buffer[pos] << 24) + (buffer[pos + 1] << 16) + (buffer[pos + 2] << 8) + buffer[pos + 3]); break; case 'V': // unsigned long (always 32 bit, little endian byte order) item = (PhpValue) unchecked (((int)buffer[pos + 3] << 24) + (buffer[pos + 2] << 16) + (buffer[pos + 1] << 8) + buffer[pos + 0]); break; case 'f': // float (machine dependent size and representation - size is always 4B) item = (PhpValue)(double)BitConverter.ToSingle(buffer, pos); break; case 'd': // double (machine dependent size and representation - size is always 8B) item = (PhpValue)BitConverter.ToDouble(buffer, pos); break; default: Debug.Fail("Invalid specifier."); return(null); } AddValue(result, name, item, op_count, j); pos += size; remains -= size; } } return(result); }
public static int ShellExec(Context ctx, string command, OutputHandling handling, PhpArray?arrayOutput, out string?stringOutput) { if (!MakeCommandSafe(ref command)) { stringOutput = null; return(-1); } using (var p = new Process()) { //IdentitySection identityConfig = null; //try { identityConfig = WebConfigurationManager.GetSection("system.web/identity") as IdentitySection; } //catch { } //if (identityConfig != null) //{ // p.StartInfo.UserName = identityConfig.UserName; // if (identityConfig.Password != null) // { // p.StartInfo.Password = new SecureString(); // foreach (char c in identityConfig.Password) p.StartInfo.Password.AppendChar(c); // p.StartInfo.Password.MakeReadOnly(); // } //} // prepare arguments { var arguments = StringBuilderUtilities.Pool.Get(); if (CurrentPlatform.IsWindows) { p.StartInfo.FileName = "cmd.exe"; AppendArgument(arguments, "/c"); } else { p.StartInfo.FileName = "/bin/bash"; AppendArgument(arguments, "-c"); } AppendArgument(arguments, command); p.StartInfo.Arguments = StringBuilderUtilities.GetStringAndReturn(arguments); } p.StartInfo.UseShellExecute = false; p.StartInfo.CreateNoWindow = true; p.StartInfo.RedirectStandardOutput = true; p.Start(); stringOutput = null; switch (handling) { case OutputHandling.String: stringOutput = p.StandardOutput.ReadToEnd(); break; case OutputHandling.ArrayOfLines: { string line; while ((line = p.StandardOutput.ReadLine()) != null) { arrayOutput?.Add(line); stringOutput = line; } break; } case OutputHandling.FlushLinesToScriptOutput: { string line; while ((line = p.StandardOutput.ReadLine()) != null) { stringOutput = line; ctx.Output.WriteLine(line); ctx.Output.Flush(); } break; } case OutputHandling.RedirectToScriptOutput: p.StandardOutput.BaseStream .CopyToAsync(ctx.OutputStream) .GetAwaiter() .GetResult(); break; } p.WaitForExit(); // return(p.ExitCode); } }
/// <summary> /// Accumulates all characters contained or not contained in the set to the string in ascending order. /// </summary> /// <param name="first">The lower bound.</param> /// <param name="last">The upper bound.</param> /// <param name="complement">Whether to return characters not contained in the string.</param> /// <returns> /// Depending on the value of the <paramref name="complement"/> the method returns the string of characters in /// this instance and a complement of this instance, respectively, intersected with the /// [<paramref name="first"/>; <paramref name="last"/>] interval. /// </returns> /// <exception cref="IndexOutOfRangeException"><paramref name="first"/> or <paramref name="last"/> are not mapped by this instance.</exception> public string ToString(char first, char last, bool complement) { if (first > last) { //throw new ArgumentException(CoreResources.GetString("last_is_less_than_first")); throw new NotImplementedException(); } int modf = first & 0x1f; int modl = last & 0x1f; int f = first >> 5; int l = last >> 5; // an optimization: if (l > lastDirty && !complement) { // sets upper bound to the last bit in the lastDirty block: l = lastDirty; modl = 31; // the whole interval is beyond the last set bit: if (f > l) { return(String.Empty); } } // if complementary set is required, we xor each item of the "flags" array by the "invert_equality" // and so invert the result of comparison with zero in the following if statement: uint invert_inequality = (complement) ? 0xffffffffU : 0U; uint flg; char c = first; var result = StringBuilderUtilities.Pool.Get(); if (f == l) { // the "first" and the "last" points to the same block: flg = flags[f] ^ invert_inequality; for (uint mask = (0x80000000U >> modf); mask > (0x80000000U >> modl); mask >>= 1) { if ((flg & mask) != 0) { result.Append(c); } c++; } } else { // the first block: flg = flags[f] ^ invert_inequality; for (uint mask = 0x80000000U >> modf; mask != 0; mask >>= 1) { if ((flg & mask) != 0) { result.Append(c); } c++; } // middle blocks (if any): for (int i = f + 1; i < l; i++) { flg = flags[i] ^ invert_inequality; for (uint mask = 0x80000000U; mask != 0; mask >>= 1) { if ((flg & mask) != 0) { result.Append(c); } c++; } } // the last block: flg = flags[l] ^ invert_inequality; for (uint mask = 0x80000000U; mask >= (0x80000000U >> modl); mask >>= 1) { if ((flg & mask) != 0) { result.Append(c); } c++; } } // return(StringBuilderUtilities.GetStringAndReturn(result)); }