mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
MNT-20500 - Admin console breaks with serialised objects (#536)
* In node browser: ** Added macro convertToJSON to recursively parse hashes and enumerables ** Added attempt/recover in macros to handle errors and not break the page ** Changed the output of serialized objects to JSON format * In both admin console and node browser: ** Adjusted consistency of the ouput when an error occurs ** Validate the depth of each hash. When we find a hash with over 1000 elements, we throw an error instead of displaying the object. Used the stop tag to effectively force an abort of the template processing preventing performance or security issues regarding very large objects.
This commit is contained in:
@@ -1,28 +1,75 @@
|
|||||||
<#macro dateFormat date>${date?string("dd MMM yyyy HH:mm:ss 'GMT'Z '('zzz')'")}</#macro>
|
<#macro dateFormat date>${date?string("dd MMM yyyy HH:mm:ss 'GMT'Z '('zzz')'")}</#macro>
|
||||||
<#escape x as jsonUtils.encodeJSONString(x)>
|
<#escape x as jsonUtils.encodeJSONString(x)>
|
||||||
|
<#assign maxDepth=1000 />
|
||||||
<#macro printPropertyValue p>
|
<#macro printPropertyValue p>
|
||||||
<#if p.value??>
|
<#attempt>
|
||||||
<#if p.value?is_date>
|
<#if p.value??>
|
||||||
|
<#if p.value?is_date>
|
||||||
"<@dateFormat p.value />"
|
"<@dateFormat p.value />"
|
||||||
<#elseif p.value?is_boolean>
|
<#elseif p.value?is_boolean>
|
||||||
${p.value?string}
|
${p.value?string}
|
||||||
<#elseif p.value?is_number>
|
<#elseif p.value?is_number>
|
||||||
${p.value?c}
|
${p.value?c}
|
||||||
<#elseif p.value?is_string>
|
<#elseif p.value?is_string>
|
||||||
"${p.value}"
|
"${p.value}"
|
||||||
<#elseif p.value?is_hash>
|
<#elseif p.value?is_hash || p.value?is_enumerable>
|
||||||
<#assign result = "{"/>
|
<#assign val>
|
||||||
|
<@convertToJSON p.value />
|
||||||
|
</#assign>
|
||||||
|
"${val}"
|
||||||
|
</#if>
|
||||||
|
<#else>
|
||||||
|
null
|
||||||
|
</#if>
|
||||||
|
<#recover>
|
||||||
|
"${.error}"
|
||||||
|
</#attempt>
|
||||||
|
</#macro>
|
||||||
|
<#macro convertToJSON v>
|
||||||
|
<#if v??>
|
||||||
|
<#if v?is_date>
|
||||||
|
"<@dateFormat v />"
|
||||||
|
<#elseif v?is_boolean>
|
||||||
|
${v?string}
|
||||||
|
<#elseif v?is_number>
|
||||||
|
${v?c}
|
||||||
|
<#elseif v?is_string>
|
||||||
|
"${v?string}"
|
||||||
|
<#elseif v?is_hash>
|
||||||
|
<#if v?keys?size gt maxDepth >
|
||||||
|
<#stop "Max depth of object achieved">
|
||||||
|
</#if>
|
||||||
|
<@compress single_line=true>
|
||||||
|
{
|
||||||
|
<#assign first = true />
|
||||||
|
<#list v?keys as key>
|
||||||
|
<#if first = false>,</#if>
|
||||||
|
"${key}":
|
||||||
|
<#if v[key]??>
|
||||||
|
<@convertToJSON v[key] />
|
||||||
|
<#else>
|
||||||
|
null
|
||||||
|
</#if>
|
||||||
|
<#assign first = false/>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
</@compress>
|
||||||
|
<#elseif v?is_enumerable>
|
||||||
|
<#if v?size gt maxDepth>
|
||||||
|
<#stop "Max depth of object achieved" >
|
||||||
|
</#if>
|
||||||
<#assign first = true />
|
<#assign first = true />
|
||||||
<#list p.value?keys as key>
|
<@compress single_line=true>
|
||||||
<#if first = false>
|
[
|
||||||
<#assign result = result + ", "/>
|
<#list v as item>
|
||||||
</#if>
|
<#if first = false>,</#if>
|
||||||
<#assign result = result + "${key} = ${p.value[key]}" />
|
<@convertToJSON item />
|
||||||
<#assign first = false/>
|
<#assign first = false/>
|
||||||
</#list>
|
</#list>
|
||||||
<#assign result = result + "}"/>
|
]
|
||||||
<#-- output the result -->
|
</@compress>
|
||||||
"${result}"
|
<#else>
|
||||||
|
${v}
|
||||||
</#if>
|
</#if>
|
||||||
<#else>
|
<#else>
|
||||||
null
|
null
|
||||||
@@ -70,7 +117,8 @@
|
|||||||
"isContent": ${val.content?string},
|
"isContent": ${val.content?string},
|
||||||
"isNodeRef": ${val.nodeRef?string},
|
"isNodeRef": ${val.nodeRef?string},
|
||||||
"isNullValue": ${val.nullValue?string}
|
"isNullValue": ${val.nullValue?string}
|
||||||
}<#if val_has_next>,</#if>
|
}
|
||||||
|
<#if val_has_next>,</#if>
|
||||||
</#list>
|
</#list>
|
||||||
],
|
],
|
||||||
"type": {
|
"type": {
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<#assign null><span style="color:red">${msg("nodebrowser.null")?html}</span></#assign>
|
<#assign null><span style="color:red">${msg("nodebrowser.null")?html}</span></#assign>
|
||||||
<#assign none><span style="color:red">${msg("nodebrowser.none")?html}</span></#assign>
|
<#assign none><span style="color:red">${msg("nodebrowser.none")?html}</span></#assign>
|
||||||
<#assign collection>${msg("nodebrowser.collection")?html}</#assign>
|
<#assign collection>${msg("nodebrowser.collection")?html}</#assign>
|
||||||
|
<#assign maxDepth=1000 />
|
||||||
<#macro dateFormat date>${date?string("dd MMM yyyy HH:mm:ss 'GMT'Z '('zzz')'")}</#macro>
|
<#macro dateFormat date>${date?string("dd MMM yyyy HH:mm:ss 'GMT'Z '('zzz')'")}</#macro>
|
||||||
<#macro propValue p>
|
<#macro propValue p>
|
||||||
<#attempt>
|
<#attempt>
|
||||||
@@ -25,50 +25,52 @@
|
|||||||
</#attempt>
|
</#attempt>
|
||||||
</#macro>
|
</#macro>
|
||||||
<#macro convertToJSON v>
|
<#macro convertToJSON v>
|
||||||
<#attempt>
|
<#if v??>
|
||||||
<#if v??>
|
<#if v?is_date>
|
||||||
<#if v?is_date>
|
<@dateFormat v />
|
||||||
<@dateFormat v />
|
<#elseif v?is_boolean>
|
||||||
<#elseif v?is_boolean>
|
${v?string}
|
||||||
${v?string}
|
<#elseif v?is_number>
|
||||||
<#elseif v?is_number>
|
${v?c}
|
||||||
${v?c}
|
<#elseif v?is_string>
|
||||||
<#elseif v?is_string>
|
"${v?string}"
|
||||||
"${v?string}"
|
<#elseif v?is_hash>
|
||||||
<#elseif v?is_hash>
|
<#if v?keys?size gt maxDepth >
|
||||||
<@compress single_line=true>
|
<#stop "Max depth of object achieved">
|
||||||
{
|
|
||||||
<#assign first = true />
|
|
||||||
<#list v?keys as key>
|
|
||||||
<#if first = false>,</#if>
|
|
||||||
"${key}":
|
|
||||||
<#if v[key]??>
|
|
||||||
<@convertToJSON v[key] />
|
|
||||||
<#else>
|
|
||||||
${null}
|
|
||||||
</#if>
|
|
||||||
<#assign first = false/>
|
|
||||||
</#list>
|
|
||||||
}
|
|
||||||
</@compress>
|
|
||||||
<#elseif v?is_enumerable>
|
|
||||||
<#assign first = true />
|
|
||||||
<@compress single_line=true>
|
|
||||||
[
|
|
||||||
<#list v as item>
|
|
||||||
<#if first = false>,</#if>
|
|
||||||
<@convertToJSON item />
|
|
||||||
<#assign first = false/>
|
|
||||||
</#list>
|
|
||||||
]
|
|
||||||
</@compress>
|
|
||||||
</#if>
|
</#if>
|
||||||
<#else>
|
<@compress single_line=true>
|
||||||
${null}
|
{
|
||||||
|
<#assign first = true />
|
||||||
|
<#list v?keys as key>
|
||||||
|
<#if first = false>,</#if>
|
||||||
|
"${key}":
|
||||||
|
<#if v[key]??>
|
||||||
|
<@convertToJSON v[key] />
|
||||||
|
<#else>
|
||||||
|
${null}
|
||||||
|
</#if>
|
||||||
|
<#assign first = false/>
|
||||||
|
</#list>
|
||||||
|
}
|
||||||
|
</@compress>
|
||||||
|
<#elseif v?is_enumerable>
|
||||||
|
<#if v?size gt maxDepth>
|
||||||
|
<#stop "Max depth of object achieved" >
|
||||||
|
</#if>
|
||||||
|
<#assign first = true />
|
||||||
|
<@compress single_line=true>
|
||||||
|
[
|
||||||
|
<#list v as item>
|
||||||
|
<#if first = false>,</#if>
|
||||||
|
<@convertToJSON item />
|
||||||
|
<#assign first = false/>
|
||||||
|
</#list>
|
||||||
|
]
|
||||||
|
</@compress>
|
||||||
</#if>
|
</#if>
|
||||||
<#recover>
|
<#else>
|
||||||
<span style="color:red">${.error}</span>
|
${null}
|
||||||
</#attempt>
|
</#if>
|
||||||
</#macro>
|
</#macro>
|
||||||
<#macro contentUrl nodeRef prop>
|
<#macro contentUrl nodeRef prop>
|
||||||
${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
|
${url.serviceContext}/api/node/${nodeRef?replace("://","/")}/content;${prop?url}
|
||||||
|
Reference in New Issue
Block a user