Skip to content

Commit

Permalink
safe print_r/var_dump when resolving property values
Browse files Browse the repository at this point in the history
ref #1162
  • Loading branch information
jakubmisek committed Feb 25, 2025
1 parent 59abe71 commit f07ce7f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 6 deletions.
6 changes: 5 additions & 1 deletion src/Peachpie.Library/Variables.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1027,7 +1027,11 @@ public override void AcceptObject(object obj)
_indent++;

// object members
var flds = (obj is IPhpPrintable printable ? printable.Properties : TypeMembersUtils.EnumerateInstanceFieldsForPrint(obj)).ToList();
var flds = obj is IPhpPrintable printable
? printable.Properties
: TypeMembersUtils.EnumerateInstanceFieldsForPrint(obj)
;

foreach (var fld in flds)
{
// [name] => value
Expand Down
29 changes: 24 additions & 5 deletions src/Peachpie.Runtime/Reflection/TypeMembersUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ public static IEnumerable<KeyValuePair<IntStringKey, PhpValue>> EnumerateVisible
return EnumerateInstanceFields(instance,
(p) => new IntStringKey(p.PropertyName),
FuncExtensions.Identity<IntStringKey>(),
(m) => m.IsVisible(caller));
(m) => m.IsVisible(caller)
);
}

/// <summary>
Expand All @@ -93,9 +94,23 @@ public static IEnumerable<KeyValuePair<string, PhpValue>> EnumerateInstanceField
{
return EnumerateInstanceFields(instance,
s_formatPropertyNameForPrint,
s_keyToString);
s_keyToString,
getValue: s_getValueWithTryCatch
);
}

static readonly Func<PhpPropertyInfo, object, PhpValue> s_getValueWithTryCatch = (p, instance) =>
{
try
{
return p.GetValue(null, instance);
}
catch (Exception e)
{
return $"Property '{p.PropertyName}' threw an exception of type {e.GetType().Name}: {e.Message}";
}
};

public static readonly Func<IntStringKey, string> s_keyToString = k => k.ToString();

public static readonly Func<PhpPropertyInfo, string> s_propertyName = p => p.PropertyName;
Expand Down Expand Up @@ -127,7 +142,9 @@ public static IEnumerable<KeyValuePair<string, PhpValue>> EnumerateInstanceField
{
return EnumerateInstanceFields(instance,
s_formatPropertyNameForDump,
s_keyToString);
s_keyToString,
getValue: s_getValueWithTryCatch
);
}

/// <summary>
Expand Down Expand Up @@ -170,9 +187,10 @@ public static IEnumerable<KeyValuePair<string, PhpValue>> EnumerateInstanceField
/// <param name="keyFormatter2">Function converting </param>
/// <param name="predicate">Optional. Predicate filtering fields.</param>
/// <param name="ignoreRuntimeFields">Whether to ignore listing runtime fields.</param>
/// <param name="getValue">Function getting property value on given <paramref name="instance"/>.</param>
/// <returns>Enumeration of fields and their values, including runtime fields.</returns>
/// <typeparam name="TKey">Enumerated pairs key. Usually <see cref="IntStringKey"/>.</typeparam>
public static IEnumerable<KeyValuePair<TKey, PhpValue>> EnumerateInstanceFields<TKey>(object instance, Func<PhpPropertyInfo, TKey> keyFormatter, Func<IntStringKey, TKey> keyFormatter2, Func<PhpPropertyInfo, bool> predicate = null, bool ignoreRuntimeFields = false)
public static IEnumerable<KeyValuePair<TKey, PhpValue>> EnumerateInstanceFields<TKey>(object instance, Func<PhpPropertyInfo, TKey> keyFormatter, Func<IntStringKey, TKey> keyFormatter2, Func<PhpPropertyInfo, bool> predicate = null, bool ignoreRuntimeFields = false, Func<PhpPropertyInfo, object, PhpValue> getValue = null)
{
Debug.Assert(instance != null);

Expand All @@ -189,7 +207,8 @@ public static IEnumerable<KeyValuePair<TKey, PhpValue>> EnumerateInstanceFields<
{
yield return new KeyValuePair<TKey, PhpValue>(
keyFormatter(p),
p.GetValue(null, instance));
getValue != null ? getValue(p, instance) : p.GetValue(null, instance)
);
}
}
}
Expand Down

0 comments on commit f07ce7f

Please sign in to comment.