Instruction:
作为 Java 安全专家，检测此代码中的安全漏洞：
## 内容1
### 文件路径：
xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/pom.xml
### 代码内容：
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.xwiki.platform</groupId>
    <artifactId>xwiki-platform-appwithinminutes</artifactId>
    <version>15.0-SNAPSHOT</version>
  </parent>
  <artifactId>xwiki-platform-appwithinminutes-ui</artifactId>
  <name>XWiki Platform - App Within Minutes - UI</name>
  <packaging>xar</packaging>
  <properties>

    <xwiki.extension.features>org.xwiki.platform:xwiki-platform-appwithinminutes</xwiki.extension.features>

    <xwiki.extension.name>App Within Minutes Application</xwiki.extension.name>
  </properties>
  <dependencies>
    <dependency>
      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-sheet-ui</artifactId>
      <version>${project.version}</version>
      <type>xar</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-livetable-ui</artifactId>
      <version>${project.version}</version>
      <type>xar</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>

      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-uiextension-ui</artifactId>
      <version>${project.version}</version>
      <type>xar</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>

      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-icon-ui</artifactId>
      <version>${project.version}</version>
      <type>xar</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>

      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-administration-ui</artifactId>
      <version>${project.version}</version>
      <type>xar</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>

      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-xclass-ui</artifactId>
      <version>${project.version}</version>
      <type>xar</type>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-localization-source-wiki</artifactId>
      <version>${project.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-rendering-macro-include</artifactId>
      <version>${project.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-rendering-macro-velocity</artifactId>
      <version>${project.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.xwiki.platform</groupId>
      <artifactId>xwiki-platform-rendering-macro-groovy</artifactId>
      <version>${project.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.xwiki.rendering</groupId>
      <artifactId>xwiki-rendering-macro-box</artifactId>
      <version>${rendering.version}</version>
      <scope>runtime</scope>
    </dependency>
    <dependency>
      <groupId>org.xwiki.rendering</groupId>
      <artifactId>xwiki-rendering-macro-html</artifactId>
      <version>${rendering.version}</version>
      <scope>runtime</scope>
    </dependency>

    <dependency>
      <groupId>org.webjars</groupId>
      <artifactId>scriptaculous</artifactId>
    </dependency>
  </dependencies>
</project>

## 内容2
### 文件路径：
xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/src/main/resources/AppWithinMinutes/CreateApplication.xml
### 代码内容：
<?xml version="1.1" encoding="UTF-8"?>

<xwikidoc version="1.5" reference="AppWithinMinutes.CreateApplication" locale="">
  <web>AppWithinMinutes</web>
  <name>CreateApplication</name>
  <language/>
  <defaultLanguage/>
  <translation>0</translation>
  <creator>xwiki:XWiki.Admin</creator>
  <parent>AppWithinMinutes.WebHome</parent>
  <author>xwiki:XWiki.Admin</author>
  <contentAuthor>xwiki:XWiki.Admin</contentAuthor>
  <version>1.1</version>
  <title>$services.localization.render('platform.appwithinminutes.appNamePageTitle')</title>
  <comment/>
  <minorEdit>false</minorEdit>
  <syntaxId>xwiki/2.1</syntaxId>
  <hidden>true</hidden>
  <content>{{include reference="AppWithinMinutes.VelocityMacros"/}}

{{velocity}}
#if ($request.wizard == 'true')
  {{include reference="AppWithinMinutes.WizardStep"/}}
#end
{{/velocity}}

{{template name="locationPicker_macros.vm" /}}

{{velocity output="false"}}
#macro (showStep)
  #appWizardHeader('name')
  <div class="wizard-help">
    <p>
      <strong>$services.localization.render('platform.appwithinminutes.wizardStepHelpTitle')</strong>
      $services.localization.render('platform.appwithinminutes.wizardStepHelpDescription')
    </p>
    <ul class="steps vertical">
      #foreach($step in $awmSteps)
        <li>
          <span class="number">$mathtool.add($foreach.index, 1)</span>
          <span class="name">$services.localization.render("appWithinMinutes.wizardStep.${step}.name")</span>
          <span class="description">$services.localization.render("appWithinMinutes.wizardStep.${step}.description")</span>
        </li>
      #end
    </ul>
  </div>
  <form action="$doc.getURL()" method="post" class="xform wizard-body">
    <fieldset>
      #locationPicker({
        'id': 'app',
        'title': {
          'label': 'platform.appwithinminutes.appNameLabel',
          'hint': 'platform.appwithinminutes.appNameHint',
          'name': 'appName'
        },
        'preview': {
          'label': 'appWithinMinutes.createApp.location.label',
          'hint': 'appWithinMinutes.createApp.location.hint'
        },
        'parent': {
          'label': 'appWithinMinutes.createApp.parent.label',
          'hint': 'appWithinMinutes.createApp.parent.hint',
          'name': 'appParentReference',
          'reference': $doc.documentReference.wikiReference,
          'placeholder': 'appWithinMinutes.createApp.parent.placeholder'
        }
      })
      <div class="appName-preview"></div>
      #appWizardFooter(1)
    </fieldset>
  </form>
#end

#macro (processStep)
  ## Check if the application already exists.
  #getAppReference
  #getAppDescriptor($appReference)
  #if ($appDescriptor)
    ## Edit an existing application.
    #getAppClassReference($appDescriptor)
    #set ($appClassRef = $classReference)
  #else
    ## Create a new application. Use the default class name.
    #set ($appCodeRef = $services.model.createSpaceReference('Code', $appReference))
    #set ($appClassRef = $services.model.createDocumentReference("$!{appReference.name}Class", $appCodeRef))
  #end
  #set ($queryString = {'wizard': true})
  #if (!$xwiki.exists($appClassRef))
    #set ($appHomeRef = $services.model.resolveDocument('', 'default', $appReference))
    #set ($discard = $queryString.putAll({
      'template': 'AppWithinMinutes.ClassTemplate',
      'parent': $services.model.serialize($appHomeRef),
      'title': "$appReference.name Class"
    }))
  #end
  $response.sendRedirect($xwiki.getURL($appClassRef, 'edit', $escapetool.url($queryString)))
#end

#macro (validateAppName)
  #getAppReference
  #if (!$appReference)
    <span class="xErrorMsg">$services.localization.render('platform.appwithinminutes.appNameEmptyError')</span>
  #else
    #getAppDescriptor($appReference)
    #if ($appDescriptor)
      ## Edit an existing application.
      #getAppClassReference($appDescriptor)
      #set ($appClassRef = $classReference)
    #else
      ## Create a new application.
      #set ($appCodeRef = $services.model.createSpaceReference('Code', $appReference))
      #set ($appClassRef = $services.model.createDocumentReference("$!{appReference.name}Class", $appCodeRef))
    #end
    <dl>
      <dt>$services.localization.render('platform.appwithinminutes.appNamePreviewHomePageUrlLabel')</dt>
      <dd><pre>$!escapetool.xml($xwiki.getDocument($appReference).externalURL)</pre></dd>
      <dt>$services.localization.render('platform.appwithinminutes.appNamePreviewCodeSpaceLabel')</dt>
      <dd>#hierarchy($appClassRef.parent)</dd>
    </dl>
    #set ($appHomeRef = $services.model.resolveDocument('', 'default', $appReference))
    #if ($appDescriptor || $xwiki.exists($appHomeRef) || $xwiki.exists($appClassRef))
      <div class="box warningmessage">
        $services.localization.render('platform.appwithinminutes.appNameIsUsedWarning')
      </div>
    #end
  #end
#end

#macro (getAppReference)
  #if ($request.resolve == 'true')
    #set ($appReference = $services.model.resolveSpace($request.appName))
  #elseif ("$!request.appName" != '')
    #set ($parentReference = $doc.documentReference.wikiReference)
    #if ("$!request.appParentReference" != '')
      #set ($parentReference = $services.model.resolveSpace($request.appParentReference))
    #end
    #set ($appReference = $services.model.createSpaceReference($request.appName, $parentReference))
  #else
    #set ($appReference = $NULL)
  #end
#end

#macro (getAppDescriptor $appReference)
  #set ($appDescriptorClassName = 'AppWithinMinutes.LiveTableClass')
  #set ($appDescriptorStatement = "from doc.object($appDescriptorClassName) as obj where doc.space = :space")
  #set ($localSpaceReference = $services.model.serialize($appReference, 'local'))
  #set ($appDescriptors = $services.query.xwql($appDescriptorStatement).bindValue('space', $localSpaceReference).execute())
  #if ($appDescriptors.size() > 0)
    #set ($appDescriptor = $xwiki.getDocument($appDescriptors.get(0)))
  #else
    #set ($appDescriptor = $NULL)
  #end
#end
{{/velocity}}

{{velocity}}
{{html clean="false"}}
#if ("$!request.appName" != '')
  #if ($xcontext.action == 'get')
    #validateAppName
  #else
    ## CSRF protection is not needed because this step only redirects to the next one passing data in the query string.
    #processStep
  #end
#elseif ($request.wizard == 'true')
  #showStep
  #set ($displayDocExtra = false)
#end
{{/html}}
{{/velocity}}</content>
  <object>
    <name>AppWithinMinutes.CreateApplication</name>
    <number>0</number>
    <className>XWiki.JavaScriptExtension</className>
    <guid>25bc0a83-b45b-4646-bf2b-a62ac7384f1d</guid>
    <class>
      <name>XWiki.JavaScriptExtension</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <cache>
        <cache>0</cache>
        <defaultValue>long</defaultValue>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>cache</name>
        <number>5</number>
        <prettyName>Caching policy</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>long|short|default|forbid</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </cache>

        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>code</name>
        <number>2</number>
        <prettyName>Code</prettyName>
        <rows>20</rows>
        <size>50</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <parse>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>parse</name>
        <number>4</number>
        <prettyName>Parse content</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </parse>
      <use>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>use</name>
        <number>3</number>
        <prettyName>Use this extension</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>currentPage|onDemand|always</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </use>
    </class>
    <property>
      <cache>long</cache>
    </property>
    <property>
      require(['jquery', 'xwiki-form-validation-async'], function($) {
  var appNameInput = $('input[name="appName"]');
  var appParentInput = $('input[name="appParentReference"]');
  var preview = $('.appName-preview');

  if (appNameInput.val() === '') {
    // We use a function instead of passing directly the promise because we want to avoid the "Uncaught (in promise)"
    // error. Basically, we want the rejected promise to be caught.
    appNameInput.validateAsync(() => Promise.reject(), 'awm');
  }

  var errorMessage = appNameInput.closest('dd').prev('dt').find('.xErrorMsg');
  if (!errorMessage.length) {
    errorMessage = $(document.createElement('span')).addClass('xErrorMsg').hide().appendTo(errorMessage.addBack());
  }

  var toggleValidationError = function(message) {
    if (message) {
      appNameInput.addClass('xErrorField');
      errorMessage.text(message).show();
      return Promise.reject();
    } else {
      appNameInput.removeClass('xErrorField');
      errorMessage.hide();
    }
  };

  var updatePreview = function(content) {
    preview.removeClass('loading').html(content);
    var error = preview.find('.xErrorMsg');
    return toggleValidationError(error.remove().text());
  };

  var fetchPreviewUpdate = function() {
    if (appNameInput.val() === '') {
      return updatePreview('<span class="xErrorMsg">$escapetool.javascript($services.localization.render("platform.appwithinminutes.appNameEmptyError"))</span>');
    } else {
      preview.addClass('loading');
      return $.get(XWiki.currentDocument.getURL('get'), appNameInput.closest('form').serialize()).then(updatePreview);
    }
  };

  appNameInput.add(appParentInput).on('input', () => {
    appNameInput.validateAsync(fetchPreviewUpdate, 500, 'awm');
  }).on('keyup', function(event) {
    // Show the error message if the user presses Enter before typing anything.
    if (event.which === 13 && appNameInput.val() === '' && !appNameInput.hasClass('xErrorField')) {
      appNameInput.validateAsync(fetchPreviewUpdate, 'awm').catch(() => appNameInput.focus());
    }
  });
});
    </property>
    <property>
      <name>Code</name>
    </property>
    <property>
      <parse>1</parse>
    </property>
    <property>
      <use>currentPage</use>
    </property>
  </object>
  <object>
    <name>AppWithinMinutes.CreateApplication</name>
    <number>0</number>
    <className>XWiki.StyleSheetExtension</className>
    <guid>3782ad9f-9bfd-43f2-9310-c196092a0ad1</guid>
    <class>
      <name>XWiki.StyleSheetExtension</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <cache>
        <cache>0</cache>
        <defaultValue>long</defaultValue>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>cache</name>
        <number>5</number>
        <prettyName>Caching policy</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>long|short|default|forbid</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </cache>

        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>code</name>
        <number>2</number>
        <prettyName>Code</prettyName>
        <rows>20</rows>
        <size>50</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <contentType>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>contentType</name>
        <number>6</number>
        <prettyName>Content Type</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>CSS|LESS</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </contentType>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <parse>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>parse</name>
        <number>4</number>
        <prettyName>Parse content</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </parse>
      <use>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>use</name>
        <number>3</number>
        <prettyName>Use this extension</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>currentPage|onDemand|always</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </use>
    </class>
    <property>
      <cache>long</cache>
    </property>
    <property>
      #template('colorThemeInit.vm')
.wizard-help {
  background-color: $theme.backgroundSecondaryColor;
  border-bottom: 1px solid $theme.borderColor;
  color: $theme.textSecondaryColor;
  float: right;
  font-size: 0.857em;
  margin: 0 0 2em 2em;
  padding: 1em;
  width: 17em;
}

.wizard-help strong {
  color: $theme.textColor;
}

.wizard-body {
  margin-right: 19em;
}

.appName-preview dl {
  color: $theme.textSecondaryColor;
  font-size: 0.8em;
  margin-bottom: 1em;
}

.appName-preview dt {
  font-weight: normal;
  margin-top: 1em;
}

.appName-preview dt:after {
  content: ":"
}

.appName-preview .breadcrumb {
  background-color: transparent;
  padding: 0;
}
    </property>
    <property>
      <contentType>CSS</contentType>
    </property>
    <property>
      <name>Style</name>
    </property>
    <property>
      <parse>1</parse>
    </property>
    <property>
      <use>currentPage</use>
    </property>
  </object>
</xwikidoc>

## 内容3
### 文件路径：
xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/src/main/resources/AppWithinMinutes/LiveTableEditSheet.xml
### 代码内容：
<?xml version="1.1" encoding="UTF-8"?>

<xwikidoc version="1.5" reference="AppWithinMinutes.LiveTableEditSheet" locale="">
  <web>AppWithinMinutes</web>
  <name>LiveTableEditSheet</name>
  <language/>
  <defaultLanguage/>
  <translation>0</translation>
  <creator>xwiki:XWiki.Admin</creator>
  <parent>AppWithinMinutes.LiveTableClass</parent>
  <author>xwiki:XWiki.Admin</author>
  <contentAuthor>xwiki:XWiki.Admin</contentAuthor>
  <version>1.1</version>
  <title/>
  <comment/>
  <minorEdit>false</minorEdit>
  <syntaxId>xwiki/2.1</syntaxId>
  <hidden>true</hidden>
  <content>{{include reference="XWiki.TemplateProviderMacros" /}}

{{include reference="AppWithinMinutes.VelocityMacros" /}}

{{velocity output="false"}}
#macro (listAvailableColumns $classReference)
  <select id="availableColumns">
    #set ($classFields = $xwiki.getDocument($classReference).getxWikiClass().properties)
    #if ($classFields.size() > 0)
      <optgroup label="$escapetool.xml($services.localization.render(
          'platform.appwithinminutes.liveTableEditorClassFieldColumnGroupLabel'))" id="classFields">
        #foreach ($field in $classFields)
          <option value="$field.name">$escapetool.xml($field.translatedPrettyName)</option>
        #end
      </optgroup>
    #end
    <optgroup label="$escapetool.xml($services.localization.render(
        'platform.appwithinminutes.liveTableEditorGenericColumnGroupLabel'))">
      #foreach ($entry in $genericColumns.entrySet())
        <option value="$entry.key" title="$escapetool.xml($entry.value.get(1))">
          $escapetool.xml($entry.value.get(0))
        </option>
      #end
    </optgroup>
  </select>
  <a href="#addColumn" class="addColumn" title="$services.localization.render(
    'platform.appwithinminutes.liveTableEditorAddColumnHint')">$services.icon.renderHTML('add')</a>
#end

#macro (displayHelpPanel)
  #set ($genericColumns = {
    'doc.title': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocTitleColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocTitleColumnDescription')
    ],
    'doc.name': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocNameColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocNameColumnDescription')
    ],
    'doc.location': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocLocationColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocLocationColumnDescription')
    ],
    'doc.author': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocAuthorColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocAuthorColumnDescription')
    ],
    'doc.creator': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocCreatorColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocCreatorColumnDescription')
    ],
    'doc.date': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocDateColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocDateColumnDescription')
    ],
    'doc.creationDate': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocCreationDateColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorDocCreationDateColumnDescription')
    ],
    '_actions': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorActionsColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorActionsColumnDescription')
    ],
    '_attachments': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorAttachmentsColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorAttachmentsColumnDescription')
    ],
    '_images': [
      $services.localization.render('platform.appwithinminutes.liveTableEditorImagesColumnName'),
      $services.localization.render('platform.appwithinminutes.liveTableEditorImagesColumnDescription')
    ]
  })
  <div class="wizard-help">
    <p>
      <strong>$services.localization.render('platform.appwithinminutes.liveTableEditorHelpTitle')</strong>
      $services.localization.render('platform.appwithinminutes.liveTableEditorHelpDescription')
    </p>
    <dl>
      #foreach ($columnId in ['doc.title', 'doc.location', 'doc.date', 'doc.author', '_actions'])
        <dt>$genericColumns.get($columnId).get(0)</dt>
        <dd>$genericColumns.get($columnId).get(1)</dd>
      #end
    </dl>
  </div>
#end

#macro (displayFormFields)
  <div class="hidden">
    ## Make sure that only the sheet content is rendered when the class is saved using AJAX.
    <input type="hidden" name="xpage" value="plain" />
    ## We prevent the class name and the data space from being edited directly. They can be specified in the URL.
    #getAppClassReference($doc)
    <input type="hidden" name="AppWithinMinutes.LiveTableClass_0_class"
      value="$escapetool.xml($services.model.serialize($classReference, 'local'))" />
    #displayPropertyValue('dataSpace', 'hidden')
    ## We have to pass the list of available columns to the JavaScript code.
    #listAvailableColumns($classReference)
  </div>
  <dl>
    <dt>
      <label for="xwikidoctitleinput">$services.localization.render('core.editors.content.titleField.label')</label>
      <span class="xHint">$services.localization.render('platform.appwithinminutes.liveTableEditorTitleHint')</span>
    </dt>
    <dd><input id="xwikidoctitleinput" type="text" name="title" value="$escapetool.xml($doc.title)"/></dd>
    <dt>
      <label for="AppWithinMinutes.LiveTableClass_0_description">
        $doc.displayPrettyName('description', false, false)
      </label>
      <span class="xHint">
        $services.localization.render('platform.appwithinminutes.liveTableEditorDescriptionHint')
      </span>
    </dt>
    <dd>#displayPropertyValue('description')</dd>
    <dt>
      <label for="AppWithinMinutes.LiveTableClass_0_columns">$doc.displayPrettyName('columns', false, false)</label>
      <span class="xHint">$services.localization.render('platform.appwithinminutes.liveTableEditorColumnsHint')</span>
    </dt>
    <dd>#displayPropertyValue('columns')</dd>
  </dl>
#end

#macro (getApplicationIcon $classReference)
  #set ($applicationIcon = '')
  ## Look for the corresponding UI extension.
  #set ($uixPointId = 'org.xwiki.platform.panels.Applications')
  #set ($uixObject = $doc.getObject('XWiki.UIExtensionClass', 'extensionPointId', $uixPointId))
  #set ($uixId = $uixObject.getValue('name'))
  #foreach ($uix in $services.uix.getExtensions($uixPointId))
    #if ($uix.id == $uixId)
      #set ($applicationIcon = $uix.parameters.icon)
    #end
  #end
  #if ("$!applicationIcon" == '')
    ## Fallback on the entry icon.
    #set ($templateProviderReference = $services.model.createDocumentReference(
      "$stringtool.removeEnd($classReference.name, 'Class')TemplateProvider",
      $classReference.parent
    ))
    #set ($entryIcon = $xwiki.getDocument($templateProviderReference).getValue('icon'))
    #if ("$!entryIcon" != '')
      #set ($applicationIcon = "icon:$entryIcon")
    #else
      #set ($applicationIcon = 'icon:application')
    #end
  #end
#end

#macro (displayIcon)
  #if ($services.uix)
    #getApplicationIcon($classReference)
    <dl>
      <dt>
        <label for="applicationIcon">
          $services.localization.render('platform.appwithinminutes.liveTableEditorIcon')
        </label>
        <span class="xHint">
          $services.localization.render('platform.appwithinminutes.liveTableEditorIconHintWithPicker',
            [$xwiki.getSkinFile('icons/silk/index_abc.png')])
        </span>
      </dt>
      <dd>
        <input id="applicationIcon" name="applicationIcon" type="text" size="10"
          value="$!escapetool.xml($applicationIcon)" />
      </dd>
    </dl>
  #end
#end

#macro (doEdit)
  {{html clean="false"}}
  #set ($liveTableObj = $doc.getObject('AppWithinMinutes.LiveTableClass', true))
  #set ($discard = $doc.use($liveTableObj))
  #set ($discard = $xwiki.ssx.use('AppWithinMinutes.LiveTableEditSheet'))
  #set ($discard = $xwiki.jsx.use('AppWithinMinutes.LiveTableEditSheet'))
  #if ("$!request.wizard" == 'true')
    #appWizardHeader('presentation')
  #end
  #displayHelpPanel()
  <div class="form-body">
    #displayFormFields()
    #displayIcon()
    #if ("$!request.wizard" == 'true')
      #appWizardFooter('presentation')
    #end
  </div>
  <div class="clearfloats"></div>
  {{/html}}

  {{iconPicker id="applicationIcon" prefix="icon:" /}}
#end

#macro (maybeGrantSpaceAdminRight $spaceRef)
  ## Grant space administration rights only if the space is new. Don't overwrite existing space preferences.
  #set ($spaceHomeRef = $services.model.resolveDocument('', 'default', $spaceRef))
  #set ($spacePrefsRef = $services.model.resolveDocument('WebPreferences', 'explicit', $spaceRef))
  #if (!$xwiki.exists($spaceHomeRef) && !$xwiki.exists($spacePrefsRef))
    #set ($spacePrefsDoc = $xwiki.getDocument($spacePrefsRef))
    #set ($discard = $spacePrefsDoc.use($spacePrefsDoc.getObject('XWiki.XWikiGlobalRights', true)))
    #set ($discard = $spacePrefsDoc.set('allow', 1))
    #set ($discard = $spacePrefsDoc.set('levels', 'admin'))
    #set ($discard = $spacePrefsDoc.set('users', $services.model.serialize($xcontext.userReference, 'default')))
    #set ($discard = $spacePrefsDoc.setTitle('$services.localization.render(''admin.preferences.title'')'))
    #set ($discard = $spacePrefsDoc.setParent($services.model.serialize($spaceHomeRef, 'default')))
    #set ($discard = $spacePrefsDoc.setHidden(true))
    #set ($discard = $spacePrefsDoc.saveWithProgrammingRights($services.localization.render(
      'platform.appwithinminutes.grantSpaceAdminRightsSaveComment')))
  #end
#end

#macro (maybeGrantSpaceAdminRights)
  ## Application space
  #set ($appReference = $doc.documentReference.parent)
  #maybeGrantSpaceAdminRight($appReference)
  ## Code space (if it's not nested inside the application space)
  #set ($className = $request.get('AppWithinMinutes.LiveTableClass_0_class'))
  #set ($classReference = $services.model.resolveDocument($className))
  #if (!$classReference.hasParent($appReference))
    #maybeGrantSpaceAdminRight($classReference.parent)
  #end
#end

#macro (updateAndSaveLiveTable)
  #set ($discard = $doc.updateObjectFromRequest('AppWithinMinutes.LiveTableClass'))
  #set ($liveTableGeneratorDoc = $xwiki.getDocument('AppWithinMinutes.LiveTableGenerator'))

  ## Generate the LiveTable by displaying the LiveTableGenerator document in the context of the current document.
  #set ($displayParameters = $services.display.createDocumentDisplayerParameters())
  #set ($discard = $displayParameters.setExecutionContextIsolated(false))
  #set ($discard = $displayParameters.setContentTranslated(true))
  #set ($generatedLiveTableContent = $services.display.content($liveTableGeneratorDoc, {
    'outputSyntaxId': 'plain/1.0',
    'displayerParameters': $displayParameters
  }))

  ## Use the generated LiveTable content for the data home page.
  #set ($dataSpaceReference = $services.model.resolveSpace($doc.getValue('dataSpace')))
  #set ($dataSpaceHomeReference = $services.model.resolveDocument('', 'default', $dataSpaceReference))
  #if ($dataSpaceHomeReference.equals($doc.documentReference) || !$xwiki.exists($dataSpaceHomeReference))
    ## Either the application space and the data space are one and the same or this is a new application and we don't
    ## want to promote the data space anymore.
    #set ($dataHomePage = $doc)
  #else
    ## The application data is stored in a different space.
    #set ($dataHomePage = $xwiki.getDocument($dataSpaceHomeReference))
    #set ($discard = $dataHomePage.setHidden(true))
    #set ($escapedAppName = $doc.documentReference.parent.name.toLowerCase().replace("'", "''"))
    #set ($discard = $dataHomePage.setTitle("${escapetool.d}services.localization.render('${escapedAppName}.dataSpace.title')"))

    ## Update the home page content.
    #set ($homePageContent = '')
    #if ("$!generatedLiveTableContent" != '')
      ## Include the entries live table in the application home page.
      #set ($escapedReference = $services.model.serialize($dataSpaceHomeReference).replaceAll('([~"])', '~$1'))
      #set ($homePageContent = "{{include reference=""$escapedReference"" /}}")
    #end
    #set ($discard = $doc.setContent($homePageContent))
  #end
  #set ($discard = $dataHomePage.setContent($generatedLiveTableContent))
  ## We assume for now that the output produced by the live table generator uses the same syntax as the code of the live
  ## table generator. We have to set the syntax because the default wiki syntax (used when creating new wiki pages)
  ## could be different than the one used by the live table generator.
  #set ($discard = $dataHomePage.setSyntax($liveTableGeneratorDoc.syntax))

  #set ($minorEdit = "$!request.minorEdit" != '')
  #set ($comment = $request.comment)
  #if ("$!comment" == '')
    #set ($comment = $services.localization.render('platform.appwithinminutes.liveTableEditorSaveComment'))
  #end

  #if ($dataHomePage != $doc)
    ## Save the data home page.
    #set ($discard = $dataHomePage.save($comment, $minorEdit))
  #end

  ## Save the application home page.
  #set ($discard = $doc.save($comment, $minorEdit))
#end

#macro (updateAndSaveIcon)
  #set ($uix = $doc.getObject('XWiki.UIExtensionClass', true))
  #set ($discard = $uix.set('name', "platform.panels.${doc.space}Application"))
  #set ($discard = $uix.set('extensionPointId', 'org.xwiki.platform.panels.Applications'))
  #set ($uixParams = [
    "label=$doc.plainTitle",
    "target=$doc.fullName",
    "icon=$request.applicationIcon"
  ])
  #set ($discard = $uix.set('parameters', $stringtool.join($uixParams, $util.newline)))
  #set ($hasWikiAdminRights = $services.security.authorization.hasAccess('admin', $doc.documentReference.wikiReference))
  #set ($discard = $uix.set('scope', "#if ($hasWikiAdminRights)wiki#{else}user#end"))
  #set ($discard = $doc.save('Updated application icon', true))
#end

#macro (doSave)
  #maybeGrantSpaceAdminRights()
  #updateAndSaveLiveTable()
  #updateAndSaveIcon()
  #if ($action == 'save')
    #if ($errorMessage)
      {{html clean="false"}}
      <div class="box errormessage">$errorMessage</div>
      {{/html}}
    #else
      ## Redirect to view mode.
      $response.sendRedirect($doc.getURL())
    #end
  #else
    #if ($errorMessage)
      $response.sendError(400, $errorMessage)
    #else
      $response.setStatus(204)
    #end
  #end
#end
{{/velocity}}

{{velocity}}
#if ("$!request.wizard" == 'true')
  {{include reference="AppWithinMinutes.WizardStep" /}}
#end
{{/velocity}}

{{velocity}}
## Determine the action button that triggered the request
#set ($action = $xcontext.action)
#foreach ($paramName in $request.getParameterMap().keySet())
  #if ($paramName.startsWith('xaction_'))
    #set ($action = $paramName.substring(8))
    #break
  #end
#end
#if ($action == 'edit')
  #doEdit()
#elseif ($action == 'save' || $action == 'saveandcontinue')
  #if ($services.csrf.isTokenValid($request.form_token))
    #doSave()
  #else
    $response.sendRedirect($services.csrf.getResubmissionURL())
  #end
#end
{{/velocity}}</content>
  <object>
    <name>AppWithinMinutes.LiveTableEditSheet</name>
    <number>0</number>
    <className>XWiki.JavaScriptExtension</className>
    <guid>dd545e46-1a0f-494a-a1db-5a45892ad4ab</guid>
    <class>
      <name>XWiki.JavaScriptExtension</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <cache>
        <cache>0</cache>
        <defaultValue>long</defaultValue>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>cache</name>
        <number>5</number>
        <prettyName>Caching policy</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>long|short|default|forbid</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </cache>

        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>code</name>
        <number>2</number>
        <prettyName>Code</prettyName>
        <rows>20</rows>
        <size>50</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <parse>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>parse</name>
        <number>4</number>
        <prettyName>Parse content</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </parse>
      <use>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>use</name>
        <number>3</number>
        <prettyName>Use this extension</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>currentPage|onDemand|always</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </use>
    </class>
    <property>
      <cache>long</cache>
    </property>
    <property>
      var XWiki = (function (XWiki) {

XWiki.LiveTableEditor = Class.create({
  initialize : function() {
    this.columnsInput = $('AppWithinMinutes.LiveTableClass_0_columns');
    this.columnsInput.hide();

    this._createColumnPicker();
    this._createDeprecationMessage();
    this._createColumnList();

    document.observe('xwiki:inline:save', this._onSave.bind(this));
  },
  containsColumn : function(name) {
    var columns = this.list.childElements();
    for(var i = 0; i < columns.length; i++) {
      if (columns[i]._name == name) {
        return true;
      }
    }
    return false;
  },
  addColumn : function(name, prettyName, isClassField) {
    if (!name || this.containsColumn(name)) {
      return;
    }
    var deprecated = !prettyName;
    prettyName = prettyName || name;
    var item = new Element('li').update('<span title="$escapetool.xml($services.localization.render('platform.appwithinminutes.liveTableEditorMoveColumnHint'))">' + prettyName.escapeHTML() + '</span><span title="$escapetool.xml($services.localization.render('platform.appwithinminutes.liveTableEditorDeleteColumnHint'))" class="delete">X</span>');
    if (deprecated) {
      item.addClassName('deprecated');
      this.deprecationMessage.show();
    }
    if (isClassField) {
      item.addClassName('classField');
    }
    item._name = name;
    item.down('.delete').observe('click', this._onDeleteColumn.bindAsEventListener(this));
    this.list.insert(item);
    Sortable.create(this.list, {overlap: 'horizontal', constraint: 'horizontal'});
  },
  getColumnPrettyName : function(columnName) {
    var options = this.columnsSelect.options;
    for(var i = 0; i < options.length; i++) {
      if (options[i].value == columnName) {
        return options[i].text;
      }
    }
    return null;
  },
  isClassField : function(columnName) {
    var options = this.columnsSelect.options;
    for(var i = 0; i < options.length; i++) {
      if (options[i].value == columnName) {
        return options[i].up().id == 'classFields';
      }
    }
    return false;
  },
  _createColumnPicker : function() {
    this.columnsSelect = $('availableColumns');
    this.columnsSelect.selectedIndex = -1;

    var addButton = this.columnsSelect.next('a.addColumn');
    addButton.observe('click', this._onAddColumn.bindAsEventListener(this));

    var picker = new Element('div', {'class': 'columnPicker'}).insert(this.columnsSelect).insert(addButton);
    this.columnsInput.up().insert(picker);
  },
  _onAddColumn : function(event) {
    event.stop();
    if (this.columnsSelect.selectedIndex >= 0) {
      var selectedOption = this.columnsSelect.options[this.columnsSelect.selectedIndex];
      this.addColumn(selectedOption.value, selectedOption.text, selectedOption.up().id == 'classFields');
      this.columnsSelect.selectedIndex = -1;
      this.columnsSelect.focus();
    }
  },
  _onDeleteColumn : function(event) {
    event.element().up('li').remove();
    // Hide deprecation message if there are no deprecated columns.
    if (this.list.select('.deprecated').length == 0) {
      this.deprecationMessage.hide();
    }
  },
  _createColumnList : function() {
    this.list = new Element('ul', {'class': 'hList'});
    this.columnsInput.up().insert(this.list);
    this.columnsInput.value.split(' ').each(function(columnName) {
      columnName = columnName.strip();
      if (columnName != '') {
        this.addColumn(columnName, this.getColumnPrettyName(columnName), this.isClassField(columnName));
      }
    }.bind(this));
  },
  _createDeprecationMessage : function() {
    this.deprecationMessage = new Element('div', {'class': 'warningmessage'}).update('$escapetool.javascript($services.localization.render('platform.appwithinminutes.liveTableEditorDeprecatedColumnsWarning'))');
    this.columnsInput.up().insert(this.deprecationMessage);
    this.deprecationMessage.hide();
    var yes = this.deprecationMessage.down('a');
    yes.observe('click', this._onRemoveDeprecatedColumns.bindAsEventListener(this));
    var no = yes.next();
    no.observe('click', function(event) {
      event.stop();
      this.deprecationMessage.hide();
    }.bindAsEventListener(this));
  },
  _onRemoveDeprecatedColumns : function(event) {
    event.stop();
    this.list.select('.deprecated').each(function(item) {
      item.remove();
    });
    this.deprecationMessage.hide();
  },
  _onSave : function() {
    var columns = [];
    this.list.childElements().each(function(item) {
      columns.push(item._name);
    });
    this.columnsInput.value = columns.join(' ');
  }
});

function initForm(form) {
  // Let the sheet handle the form submit. The form is submitted by default to the preview action which dispatches the
  // request to the save action if the save button is detected on the request parameters. By submitting to the edit
  // action the edit sheet is evaluated and thus it can handle the save by itself.
  form.action = XWiki.currentDocument.getURL('edit');

  // Apply the vertical form layout standard.
  form.addClassName('xform');

  // Remove the preview button.
  form.down("input[name='action_preview']").remove();

  // Rename the save buttons.
  form.down("input[name='action_save']").name = 'xaction_save';
  form.down("input[name='action_saveandcontinue']").name = 'xaction_saveandcontinue';

  // Make sure the 'Save & Continue' button is submitted when clicked.
  document.observe('xwiki:inline:save', function(event) {
    event = event.memo.originalEvent;
    if (event.memo['continue']) {
      var submitButton = event.memo.originalEvent.element();
      submitButton.insert({after: new Element('input', {type: 'hidden', 'name': submitButton.name})});
      (function () {
        submitButton.next().remove();
      }).defer();
    }
  }.bindAsEventListener(window));

  new XWiki.LiveTableEditor();
}

function init() {
  var form = $('inline');
  if (form) {
    require(['scriptaculous/dragdrop'], function() {
      initForm(form);
    });
  }
  return form;
}

(XWiki.domIsLoaded && init()) || document.observe('xwiki:dom:loaded', init);

// Allow widgets to catch the save event before the form is submitted when the 'Save & Continue' button is clicked. We
// need this hack because the 'Save & Continue' handler from actionbuttons.js is added right after the page is loaded,
// before any other code can register its own listener.
document.observe('xwiki:actions:save', function(event) {
  document.fire('xwiki:inline:save', {originalEvent: event});
}.bindAsEventListener(window));

return XWiki;
}(XWiki || {}));
    </property>
    <property>
      <name>Code</name>
    </property>
    <property>
      <parse>1</parse>
    </property>
    <property>
      <use>onDemand</use>
    </property>
  </object>
  <object>
    <name>AppWithinMinutes.LiveTableEditSheet</name>
    <number>0</number>
    <className>XWiki.RequiredRightClass</className>
    <guid>c8e4a863-1a27-47d5-bb40-a37bcd27508d</guid>
    <class>
      <name>XWiki.RequiredRightClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <level>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <multiSelect>0</multiSelect>
        <name>level</name>
        <number>1</number>
        <picker>0</picker>
        <prettyName>level</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators> ,|</separators>
        <size>1</size>
        <sort>none</sort>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <values>edit|programming</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </level>
    </class>
    <property>
      <level>programming</level>
    </property>
  </object>
  <object>
    <name>AppWithinMinutes.LiveTableEditSheet</name>
    <number>0</number>
    <className>XWiki.SheetDescriptorClass</className>
    <guid>b4421c7c-8010-487f-aa21-8abb799e011e</guid>
    <class>
      <name>XWiki.SheetDescriptorClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <action>
        <customDisplay/>
        <disabled>0</disabled>
        <name>action</name>
        <number>1</number>
        <picker>0</picker>
        <prettyName>Action</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </action>
    </class>
    <property>
      <action>edit</action>
    </property>
  </object>
  <object>
    <name>AppWithinMinutes.LiveTableEditSheet</name>
    <number>0</number>
    <className>XWiki.StyleSheetExtension</className>
    <guid>d6100cff-9fc3-46be-b56a-0561cadf45f9</guid>
    <class>
      <name>XWiki.StyleSheetExtension</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <cache>
        <cache>0</cache>
        <defaultValue>long</defaultValue>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>cache</name>
        <number>5</number>
        <prettyName>Caching policy</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>long|short|default|forbid</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </cache>

        <contenttype>PureText</contenttype>
        <disabled>0</disabled>
        <editor>PureText</editor>
        <name>code</name>
        <number>2</number>
        <prettyName>Code</prettyName>
        <rows>20</rows>
        <size>50</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>

      <contentType>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>contentType</name>
        <number>6</number>
        <prettyName>Content Type</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>CSS|LESS</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </contentType>
      <name>
        <disabled>0</disabled>
        <name>name</name>
        <number>1</number>
        <prettyName>Name</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </name>
      <parse>
        <disabled>0</disabled>
        <displayFormType>select</displayFormType>
        <displayType>yesno</displayType>
        <name>parse</name>
        <number>4</number>
        <prettyName>Parse content</prettyName>
        <unmodifiable>0</unmodifiable>
        <classType>com.xpn.xwiki.objects.classes.BooleanClass</classType>
      </parse>
      <use>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>use</name>
        <number>3</number>
        <prettyName>Use this extension</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>currentPage|onDemand|always</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </use>
    </class>
    <property>
      <cache>long</cache>
    </property>
    <property>
      #template('colorThemeInit.vm')
#inline .hList {
  font-size: 90%;
  list-style: none outside none;
  margin: 0;
  padding: 0;
}

#inline .hList li {
  border: 1px solid $theme.borderColor;
  cursor: move;
  display: inline-block;
  margin: 0 0.2em 0.2em 0;
  padding: 0.1em 0.6em;
}

#inline .hList li:hover {
  background-color: $theme.highlightColor;
}

#inline .hList li .delete {
  color: $theme.pageContentBackgroundColor;
  cursor: pointer;
  font-size: 70%;
  font-weight: bold;
  position: absolute;
  text-decoration: none !important;
  vertical-align: super;
}

#inline .hList li:hover .delete {
  color: $theme.textPrimaryColor;
}

#inline .hList li .delete:hover {
  color: $theme.notificationErrorColor;
}

#inline .hList li.deprecated {
  border: 1px solid $theme.notificationWarningColor;
}

#inline .hList li.classField {
  font-weight: bolder;
}

.columnPicker {
  margin-bottom: .3em;
}

.columnPicker select {
  width: auto;
}

.columnPicker a.addColumn {
  margin: 0 .5em;
  padding: 0;
}

.form-body {
  margin-right: 19em;
}

.wizard-help {
  background-color: $theme.backgroundSecondaryColor;
  border-bottom: 1px solid $theme.borderColor;
  color: $theme.textSecondaryColor;
  float: right;
  font-size: 0.857em;
  margin: 0 0 2em 2em;
  padding: 1em;
  width: 17em;
}

.wizard-help dl, .wizard-help p {
  font-size: 0.9em;
}

.wizard-help dl {
  margin-left: 1em;
}

.wizard-help dt, .wizard-help strong {
  color: $theme.textColor;
}

/* Fix WYSIWYG Editor display. */
#inline .xToolbar div.clearfloats {
  clear: left;
}
    </property>
    <property>
      <contentType/>
    </property>
    <property>
      <name>Style</name>
    </property>
    <property>
      <parse>1</parse>
    </property>
    <property>
      <use>onDemand</use>
    </property>
  </object>
</xwikidoc>

## 内容4
### 文件路径：
xwiki-platform-core/xwiki-platform-appwithinminutes/xwiki-platform-appwithinminutes-ui/src/main/resources/AppWithinMinutes/Translations.xml
### 代码内容：
<?xml version="1.1" encoding="UTF-8"?>

<xwikidoc version="1.5" reference="AppWithinMinutes.Translations" locale="">
  <web>AppWithinMinutes</web>
  <name>Translations</name>
  <language/>
  <defaultLanguage>en</defaultLanguage>
  <translation>0</translation>
  <creator>xwiki:XWiki.Admin</creator>
  <parent>AppWithinMinutes.WebHome</parent>
  <author>xwiki:XWiki.Admin</author>
  <contentAuthor>xwiki:XWiki.Admin</contentAuthor>
  <version>1.1</version>
  <title/>
  <comment/>
  <minorEdit>false</minorEdit>
  <syntaxId>plain/1.0</syntaxId>
  <hidden>true</hidden>
  <content>### Home page
platform.appwithinminutes.homePageTitle=App Within Minutes
platform.appwithinminutes.description=Create collaborative web applications within minutes, based on XWiki's powerful structured data management system.
platform.appwithinminutes.createAppButtonLabel=Create Application
platform.appwithinminutes.appsLiveTableHeading=Applications
platform.appwithinminutes.appsLiveTable.doc.title=Application
platform.appwithinminutes.appsLiveTable.doc.author=Last author
platform.appwithinminutes.appsLiveTable.doc.date=Update date
platform.appwithinminutes.appsLiveTable._actions=Actions
platform.appwithinminutes.grantSpaceAdminRightsSaveComment=Grant space administration rights.

### AWM Applications panel entry
platform.appwithinminutes.appPanelCreateEntry=Create your own!

### Wizard step
platform.appwithinminutes.wizardStepHeading=Step {0} \u2014 {1}
appWithinMinutes.wizardStep.name.name=Name
appWithinMinutes.wizardStep.name.title=Name your application
appWithinMinutes.wizardStep.name.description=Choose the application name
appWithinMinutes.wizardStep.structure.name=Structure
appWithinMinutes.wizardStep.structure.title=Structure your data
appWithinMinutes.wizardStep.structure.description=Describe the application data
appWithinMinutes.wizardStep.entries.name=Entries
appWithinMinutes.wizardStep.entries.title=Locate your data
appWithinMinutes.wizardStep.entries.description=Choose where to store the data
appWithinMinutes.wizardStep.presentation.name=Presentation
appWithinMinutes.wizardStep.presentation.title=Customize your application home page
appWithinMinutes.wizardStep.presentation.description=Customize the application home page
platform.appwithinminutes.wizardStepNextButtonLabel=Next Step
platform.appwithinminutes.wizardStepNextButtonTip=Go to next step
platform.appwithinminutes.wizardStepFinishButtonLabel=Finish
platform.appwithinminutes.wizardStepFinishButtonTip=Go to the application home page
platform.appwithinminutes.wizardStepPreviousButtonLabel=Previous Step
platform.appwithinminutes.wizardStepPreviousButtonTip=Go to previous step
platform.appwithinminutes.wizardStepHelpTitle=Steps
platform.appwithinminutes.wizardStepHelpDescription=This wizard will guide you through the process of creating an application. These are the steps you'll take:

### Wizard Step 1: Application Name
appWithinMinutes.createApp.location.label=Location
appWithinMinutes.createApp.location.hint=The location in the page hierarchy where the application will be created.
appWithinMinutes.createApp.parent.label=Parent
appWithinMinutes.createApp.parent.hint=The parent of the new application. Leave this field empty if you want to create a top level application.
appWithinMinutes.createApp.parent.placeholder=Path.To.Parent
appWithinMinutes.codeSpace.title=Code
appWithinMinutes.codeSpace.description=This is the place where the application code is located.
appWithinMinutes.codeSpace.hiddenPagesInfo=The hidden pages are also listed, even though your current user profile settings prevent to do so, otherwise none of the application code pages would be visible because they are all hidden by default.
platform.appwithinminutes.appNamePageTitle=Create Application
platform.appwithinminutes.appNameLabel=Application Name
platform.appwithinminutes.appNameHint=The application name determines the homepage URL and the location where the application code is stored.
platform.appwithinminutes.appNamePreviewHomePageUrlLabel=Application homepage URL
platform.appwithinminutes.appNamePreviewCodeSpaceLabel=Application code location
platform.appwithinminutes.appNameIsUsedWarning=This application already exists. If you go to the next step you will be editing the existing application.
platform.appwithinminutes.appNameEmptyError=Please enter the application name.

### Wizard Step 2: Application Structure
platform.appwithinminutes.classEditorPaletteTitle=Field Palette
platform.appwithinminutes.classEditorPaletteHint=Drag & drop fields from the palette to create the form that will be used to input your data.
platform.appwithinminutes.classEditorCanvasHint=Drag fields from the palette and drop them in this area.

platform.appwithinminutes.classEditorUpdateTemplateLabel=Update the template
platform.appwithinminutes.classEditorUpdateTemplateHint=The template ({0}) stores the default field values.
platform.appwithinminutes.classEditorUpdateSheetLabel=Update the sheet
platform.appwithinminutes.classEditorUpdateSheetHint=The sheet ({0}) is used to display and edit the structured data.
platform.appwithinminutes.classEditorUpdateTranslationsLabel=Update the translation
platform.appwithinminutes.classEditorUpdateTranslationsHint=Update the translation of field pretty names and list values ({0}).

platform.appwithinminutes.classEditorMultipleSheetsWarning=This class has multiple sheets.
platform.appwithinminutes.classEditorDuplicateFieldNameError=The class has two fields with the same name: {0}
platform.appwithinminutes.classEditorTemplateSaveComment=Update default values
platform.appwithinminutes.classEditorBindSheetSaveComment=Bind class sheet
platform.appwithinminutes.classEditorSheetSaveComment=Update class sheet
platform.appwithinminutes.classEditorTranslationsSaveComment=Update translations

platform.appwithinminutes.classEditorStandardCategoryName=Standard
platform.appwithinminutes.classEditorPickersCategoryName=Pickers
platform.appwithinminutes.classEditorDocumentCategoryName=Page
platform.appwithinminutes.classEditorAdvancedCategoryName=Advanced

platform.appwithinminutes.classEditorDBListFieldName=Database List
platform.appwithinminutes.classEditorGroupsFieldName=Group
platform.appwithinminutes.classEditorUsersFieldName=User
platform.appwithinminutes.classEditorDateFieldName=Date
platform.appwithinminutes.classEditorStaticListFieldName=Static List
platform.appwithinminutes.classEditorBooleanFieldName=Boolean
platform.appwithinminutes.classEditorNumberFieldName=Number
platform.appwithinminutes.classEditorTextAreaFieldName=Long Text
platform.appwithinminutes.classEditorStringFieldName=Short Text
platform.appwithinminutes.classEditorContentFieldName=Content
platform.appwithinminutes.classEditorTitleFieldName=Title
platform.appwithinminutes.classEditorPageFieldName=Page

platform.appwithinminutes.classEditorDeleteFieldLabel=Delete
platform.appwithinminutes.classEditorConfigureFieldLabel=Configure
platform.appwithinminutes.classEditorPreviewFieldLabel=Preview
platform.appwithinminutes.classEditorPreviewFieldHint=Hide configuration panel and apply changes
platform.appwithinminutes.classEditorMoveFieldLabel=Move
platform.appwithinminutes.classEditorMoveFieldHint=Drag and drop to change the order

platform.appwithinminutes.classEditorFieldDefaultValueToolTip=Default value

### Date Picker
platform.appwithinminutes.classEditorDatePickerAcceptSelectedDate=OK
platform.appwithinminutes.classEditorDatePickerClearSelectedDate=Clear
platform.appwithinminutes.classEditorDatePickerSelectCurrentTime=Now
platform.appwithinminutes.classEditorDatePickerSelectCurrentDate=Today

### Static List Editor
platform.appwithinminutes.classEditorStaticListEditorItemValueLabel=Value
platform.appwithinminutes.classEditorStaticListEditorItemIDLabel=ID
platform.appwithinminutes.classEditorStaticListEditorAddItemLabel=Add
platform.appwithinminutes.classEditorStaticListEditorDeleteItemLabel=Delete

appWithinMinutes.templateProviderEditor.hint=Application entries are wiki pages that contain structured data.
appWithinMinutes.templateProviderEditor.icon.hint=The icon associated with an application entry.
appWithinMinutes.templateProviderEditor.description.hint=Short description of an application entry.
appWithinMinutes.templateProviderEditor.visibilityRestrictions.name=Where to create the entries from
appWithinMinutes.templateProviderEditor.visibilityRestrictions.hint=If no location is selected, the entries can be created from any page.
appWithinMinutes.templateProviderEditor.creationRestrictions.name=Where to create the entries
appWithinMinutes.templateProviderEditor.creationRestrictions.hint=If no location is selected, the entries can be created anywhere in the wiki.
appWithinMinutes.templateProviderEditor.creationRestrictionsAreSuggestions.name=Don't enforce entry location
appWithinMinutes.templateProviderEditor.creationRestrictionsAreSuggestions.hint=Use the locations specified above only as suggestions, allowing the user to select a different location when creating an application entry.
appWithinMinutes.templateProviderEditor.terminal.hint=Whether the application entries should be terminal pages or not.

### Wizard Step 3: Application Presentation
platform.appwithinminutes.liveTableEditorClassFieldColumnGroupLabel=Application fields
platform.appwithinminutes.liveTableEditorGenericColumnGroupLabel=Generic columns
platform.appwithinminutes.liveTableEditorHelpTitle=Tip
platform.appwithinminutes.liveTableEditorHelpDescription=Generic live table columns are independent of your application structure. They provide information about the pages that hold your application data.
platform.appwithinminutes.liveTableEditorDocTitleColumnName=Page Title
platform.appwithinminutes.liveTableEditorDocTitleColumnDescription=The title of the page that contains application data
platform.appwithinminutes.liveTableEditorDocNameColumnName=Page Name
platform.appwithinminutes.liveTableEditorDocNameColumnDescription=The name of the page that contains application data
platform.appwithinminutes.liveTableEditorDocLocationColumnName=Location
platform.appwithinminutes.liveTableEditorDocLocationColumnDescription=The location of the page that contains application data
platform.appwithinminutes.liveTableEditorDocAuthorColumnName=Last Author
platform.appwithinminutes.liveTableEditorDocAuthorColumnDescription=The user who last edited the application data
platform.appwithinminutes.liveTableEditorDocCreatorColumnName=Creator
platform.appwithinminutes.liveTableEditorDocCreatorColumnDescription=The user who created the application data
platform.appwithinminutes.liveTableEditorDocDateColumnName=Date
platform.appwithinminutes.liveTableEditorDocDateColumnDescription=The date when the application data was last edited
platform.appwithinminutes.liveTableEditorDocCreationDateColumnName=Creation Date
platform.appwithinminutes.liveTableEditorDocCreationDateColumnDescription=The date when the application data was created
platform.appwithinminutes.liveTableEditorActionsColumnName=Actions
platform.appwithinminutes.liveTableEditorActionsColumnDescription=A list of actions that can be performed on the application data, such as edit and delete
platform.appwithinminutes.liveTableEditorAttachmentsColumnName=Attachments
platform.appwithinminutes.liveTableEditorAttachmentsColumnDescription=A special column to display links to the attachments of a data page
platform.appwithinminutes.liveTableEditorImagesColumnName=Images
platform.appwithinminutes.liveTableEditorImagesColumnDescription=A special column to display the images attached to a data page
platform.appwithinminutes.liveTableEditorAvatarColumnName=Avatar
platform.appwithinminutes.liveTableEditorAvatarColumnDescription=A special column to display the user avatar. Works only for a table bound to the XWiki.XWikiUsers class
platform.appwithinminutes.liveTableEditorTitleHint=The application title to be displayed on the application home page, on the applications panel and live table, on the breadcrumb, etc.
platform.appwithinminutes.liveTableEditorDescriptionHint=The content to be displayed on the homepage above the live table with the application data. Use it to describe the application.
platform.appwithinminutes.liveTableEditorColumnsHint=Select the columns you would like to include in the live table displayed on the application home page.
platform.appwithinminutes.liveTableEditorSaveComment=Update LiveTable
platform.appwithinminutes.liveTableEditorMoveColumnHint=Drag and drop to change the order
platform.appwithinminutes.liveTableEditorDeleteColumnHint=Delete
platform.appwithinminutes.liveTableEditorAddColumnHint=Add selected column
platform.appwithinminutes.liveTableEditorDeprecatedColumnsWarning=Some columns are deprecated, probably because the corresponding application fields have been deleted. Do you want to remove them? <a href="">Yes</a> / <a href="">No</a>
platform.appwithinminutes.liveTableEditorIcon=Icon
platform.appwithinminutes.liveTableEditorIconHintWithPicker=The application icon. You can select an icon from the icon picker or you can reference an attached image.

### Wizard Step 4: Application home page
platform.appwithinminutes.appLiveTableHeading=Entries
platform.appwithinminutes.appLiveTableEditEntryActionName=Edit
platform.appwithinminutes.appLiveTableDeleteEntryActionName=Delete
platform.appwithinminutes.appHomePageActionsHeading=Actions
platform.appwithinminutes.appHomePageAddEntryLabel=Add
platform.appwithinminutes.appHomePageAddEntryHint=Add new entry
platform.appwithinminutes.appHomePageEntryNameLabel=Entry name:
platform.appwithinminutes.appHomePageDeleteEntriesLabel=Delete all entries
platform.appwithinminutes.appHomePageEditAppLabel=Edit application
platform.appwithinminutes.appHomePageTranslateAppLabel=Translate application
platform.appwithinminutes.appHomePageDeleteAppLabel=Delete application
platform.appwithinminutes.appHomePageMovedWarning=The application might not function correctly because it has been renamed or moved without updating the code. Please edit the application and follow the steps in order to update the code.
AppWithinMinutes.LiveTableClass_description=Description
AppWithinMinutes.LiveTableClass_columns=Live Table Columns

### Delete application dialog
platform.appwithinminutes.deleteAppConfirmation=The application {0} and ALL its entries will be deleted. Are you sure you want to continue?
platform.appwithinminutes.deleteAppEntriesConfirmation=ALL the entries of the application {0} will be deleted. Are you sure you want to continue?
platform.appwithinminutes.deleteAppDoesNotExistError=The specified application does not exist.
platform.appwithinminutes.deleteAppInvalidAppError=The specified name is not a valid App Within Minutes application.
platform.appwithinminutes.deleteAppNotSpecifiedError=No application name was specified.

### Rename Application
appWithinMinutes.renameApp.label=Rename Application
appWithinMinutes.renameApp.close=Close
appWithinMinutes.renameApp.changeAppTitleInfo=You can change the application title without renaming the application just by editing the application home page.
appWithinMinutes.renameApp.regenerateAppCodeWarning=The application code is going to be regenerated if you rename the application. Code customizations will be overwritten as a consequence.
appWithinMinutes.renameApp.newName.label=New Name
appWithinMinutes.renameApp.pageExistsError=A page with this name already exists at the selected location.
appWithinMinutes.renameApp.locationForbiddenError=You are not allowed to move the application to the selected location.
appWithinMinutes.renameApp.location.label=New Location
appWithinMinutes.renameApp.location.hint=The location in the page hierarchy where to move the application.
appWithinMinutes.renameApp.parent.label=New Parent
appWithinMinutes.renameApp.parent.hint=The new parent page. Leave this field empty if you want to move the application to the top of the page hierarchy.
appWithinMinutes.renameApp.inProgress=Renaming application...
appWithinMinutes.renameApp.done=Application renamed
appWithinMinutes.renameApp.failed=Failed to rename the application

### Deprecated keys
### Since 8.4
platform.appwithinminutes.appNamePreviewClassReferenceLabel=Application class
platform.appwithinminutes.appNamePreviewDataSpaceLabel=Application data location

platform.appwithinminutes.liveTableEditorDocSpaceColumnName=Space
platform.appwithinminutes.liveTableEditorDocSpaceColumnDescription=The name of the space containing the application entry
platform.appwithinminutes.liveTableEditorDocFullNameColumnName=Page full name
platform.appwithinminutes.liveTableEditorDocFullNameColumnDescription=The name of the page that contains the application entry, prefixed with the space name

#@deprecated appWithinMinutes.wizardStep.name.name
platform.appwithinminutes.wizardStep1Name=Name
#@deprecated appWithinMinutes.wizardStep.name.title
platform.appwithinminutes.wizardStep1Title=Name your application
#@deprecated appWithinMinutes.wizardStep.name.description
platform.appwithinminutes.wizardStep1Description=Choose the application name
#@deprecated appWithinMinutes.wizardStep.structure.name
platform.appwithinminutes.wizardStep2Name=Structure
#@deprecated appWithinMinutes.wizardStep.structure.title
platform.appwithinminutes.wizardStep2Title=Structure your data
#@deprecated appWithinMinutes.wizardStep.structure.description
platform.appwithinminutes.wizardStep2Description=Describe the application data
#@deprecated appWithinMinutes.wizardStep.presentation.name
platform.appwithinminutes.wizardStep3Name=Presentation
#@deprecated appWithinMinutes.wizardStep.presentation.title
platform.appwithinminutes.wizardStep3Title=Customize your application homepage
#@deprecated appWithinMinutes.wizardStep.presentation.description
platform.appwithinminutes.wizardStep3Description=Customize the application homepage

### Since 11.0
platform.appwithinminutes.appsLiveTable.doc.space=Application name
appWithinMinutes.classEditor.title={0} Structure
appWithinMinutes.templateProviderEditor.title={0} Entries</content>
  <object>
    <name>AppWithinMinutes.Translations</name>
    <number>0</number>
    <className>XWiki.TranslationDocumentClass</className>
    <guid>24e055eb-5de1-4dd9-8c46-03d474d8782b</guid>
    <class>
      <name>XWiki.TranslationDocumentClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <scope>
        <cache>0</cache>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText>forbidden</freeText>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>scope</name>
        <number>1</number>
        <prettyName>Scope</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <unmodifiable>0</unmodifiable>
        <values>GLOBAL|WIKI|USER|ON_DEMAND</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </scope>
    </class>
    <property>
      <scope>WIKI</scope>
    </property>
  </object>
</xwikidoc>

Output:
【漏洞类型】权限控制漏洞
【严重性】High
【漏洞摘要】此代码存在权限控制漏洞，允许用户在没有适当权限的情况下创建或编辑应用程序。具体表现为，`maybeGrantSpaceAdminRights`宏在没有验证用户是否具有脚本（script）权限的情况下，授予空间管理员权限。这可能导致未经授权的用户获得对应用程序空间的管理员权限，从而能够执行敏感操作，如修改应用程序代码或删除应用程序。
【关键代码模式】
- `maybeGrantSpaceAdminRight`宏
- `$services.security.authorization.hasAccess('script', $xcontext.userReference, $spaceHomeRef)`
- `$services.security.authorization.hasAccess('admin', $doc.documentReference.wikiReference)`
- `$response.sendRedirect($services.csrf.getResubmissionURL())`
【修复方法说明】修复方法通过在授予权限之前检查用户是否具有脚本权限来解决问题。这确保了只有具有适当权限的用户才能创建或编辑应用程序。此外，修复还增加了对脚本权限的检查，以防止在没有此权限的情况下保存应用程序。


Instruction:
作为 Java 安全专家，检测此代码中的安全漏洞：
## 内容1
### 文件路径：
xwiki-platform-core/xwiki-platform-administration/xwiki-platform-administration-ui/src/main/resources/XWiki/AdminTemplatesSheet.xml
### 代码内容：
<?xml version="1.1" encoding="UTF-8"?>

<xwikidoc version="1.5" reference="XWiki.AdminTemplatesSheet" locale="">
  <web>XWiki</web>
  <name>AdminTemplatesSheet</name>
  <language/>
  <defaultLanguage/>
  <translation>0</translation>
  <creator>xwiki:XWiki.Admin</creator>
  <parent>XWiki.XWikiPreferences</parent>
  <author>xwiki:XWiki.Admin</author>
  <contentAuthor>xwiki:XWiki.Admin</contentAuthor>
  <version>1.1</version>
  <title>Admin Templates Sheet</title>
  <comment/>
  <minorEdit>false</minorEdit>
  <syntaxId>xwiki/2.0</syntaxId>
  <hidden>true</hidden>
  <content>{{velocity}}
## Create form, left column.
(% class="col-xs-12 col-md-6" %)(((
(% id="HAdminTemplatesCreateProvider" %)
== {{translation key="admin.templates.createprovider"/}} ==

{{html}}
  <form class="xform" action="$doc.getURL('create')" method="post">
    <fieldset>
    #template('locationPicker_macros.vm')
    #locationPicker({
      'id': 'target',
      'title': {
        'label': 'core.create.title',
        'hint': 'core.create.title.hint',
        'name': 'title',
        'placeholder': 'admin.templates.createprovider.defaultdocname'
      },
      'preview': {
        'label': 'core.create.locationPreview.label',
        'hint': 'core.create.locationPreview.hint'
      },
      'parent': {
        'label': 'core.create.spaceReference.label',
        'hint': 'core.create.spaceReference.hint',
        'name': 'spaceReference',
        'reference': $doc.documentReference.lastSpaceReference,
        'placeholder': 'core.create.spaceReference.placeholder'
      },
      'name': {
        'label': 'core.create.name.label',
        'hint': 'core.create.name.hint',
        'name': 'name',
        'value': '',
        'placeholder': 'admin.templates.createprovider.defaultdocname'
      }
    })
    #if ($isAdvancedUser || $isSuperAdmin)

            <input type="checkbox" id="terminal" name="tocreate" value="terminal" checked="checked" />
            $services.localization.render('core.create.terminal.label')

          $services.localization.render('core.create.terminal.hint')

    #else
      <input type="hidden" id="terminal" name="tocreate" value="terminal" />
    #end

      <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
      <input type="hidden" name="parent" value="XWiki.TemplateProviderClass"/>
      <input type="hidden" name="template" value="XWiki.TemplateProviderTemplate"/>
      <input id="createTemplateProvider" type="submit" value="$services.localization.render('admin.templates.createprovider.create')" class="button"/>

    </fieldset>
  </form>
{{/html}}
)))

## Available providers list, right column.
#set($availableProviders = $services.query.hql("
  , BaseObject obj
  WHERE
    doc.fullName=obj.name and obj.className='XWiki.TemplateProviderClass' and doc.fullName!='XWiki.TemplateProviderTemplate'
  ORDER BY
    doc.fullName").execute())
#if($availableProviders.size() > 0)
  (% class="col-xs-12 col-md-6" %)(((
  (% id="HAdminTemplatesProvidersList" %)
  == {{translation key="admin.templates.providerslist"/}} ==

    #foreach($providerFullname in $availableProviders)
      * [[$services.rendering.escape($xwiki.getDocument($providerFullname).plainTitle, $xwiki.currentContentSyntaxId)>>$providerFullname]]
    #end
  )))
#end

{{/velocity}}</content>
  <object>
    <name>XWiki.AdminTemplatesSheet</name>
    <number>0</number>
    <className>XWiki.ConfigurableClass</className>
    <guid>b03bf517-5cff-4873-a899-7f87e8829aaa</guid>
    <class>
      <name>XWiki.ConfigurableClass</name>
      <customClass/>
      <customMapping/>
      <defaultViewSheet/>
      <defaultEditSheet/>
      <defaultWeb/>
      <nameField/>
      <validationScript/>
      <categoryIcon>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>categoryIcon</name>
        <number>11</number>
        <picker>0</picker>
        <prettyName>categoryIcon</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </categoryIcon>
      <codeToExecute>
        <contenttype>VelocityWiki</contenttype>
        <customDisplay/>
        <disabled>0</disabled>
        <editor>---</editor>
        <hint/>
        <name>codeToExecute</name>
        <number>7</number>
        <picker>0</picker>
        <prettyName>codeToExecute</prettyName>
        <rows>5</rows>
        <size>40</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.TextAreaClass</classType>
      </codeToExecute>
      <configurationClass>
        <cache>0</cache>
        <classname/>
        <customDisplay/>
        <defaultValue/>
        <disabled>0</disabled>
        <displayType>input</displayType>
        <freeText/>
        <hint/>
        <idField/>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>configurationClass</name>
        <number>3</number>
        <picker>1</picker>
        <prettyName>configurationClass</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators/>
        <size>30</size>
        <sort>none</sort>
        <sql/>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <valueField/>
        <classType>com.xpn.xwiki.objects.classes.PageClass</classType>
      </configurationClass>
      <displayBeforeCategory>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>displayBeforeCategory</name>
        <number>10</number>
        <picker>0</picker>
        <prettyName>displayBeforeCategory</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </displayBeforeCategory>
      <displayInCategory>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>displayInCategory</name>
        <number>9</number>
        <picker>0</picker>
        <prettyName>displayInCategory</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </displayInCategory>
      <displayInSection>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>displayInSection</name>
        <number>1</number>
        <picker>0</picker>
        <prettyName>displayInSection</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </displayInSection>
      <heading>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>heading</name>
        <number>2</number>
        <picker>0</picker>
        <prettyName>heading</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </heading>
      <iconAttachment>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>iconAttachment</name>
        <number>8</number>
        <picker>0</picker>
        <prettyName>iconAttachment</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </iconAttachment>
      <linkPrefix>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>linkPrefix</name>
        <number>5</number>
        <picker>0</picker>
        <prettyName>linkPrefix</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.StringClass</classType>
      </linkPrefix>
      <propertiesToShow>
        <cache>0</cache>
        <customDisplay/>
        <defaultValue/>
        <disabled>0</disabled>
        <displayType>input</displayType>
        <freeText/>
        <hint/>
        <largeStorage>0</largeStorage>
        <multiSelect>1</multiSelect>
        <name>propertiesToShow</name>
        <number>6</number>
        <picker>0</picker>
        <prettyName>propertiesToShow</prettyName>
        <relationalStorage>1</relationalStorage>
        <separator> </separator>
        <separators> ,|</separators>
        <size>20</size>
        <sort>none</sort>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <values/>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </propertiesToShow>
      <scope>
        <cache>0</cache>
        <customDisplay/>
        <defaultValue/>
        <disabled>0</disabled>
        <displayType>select</displayType>
        <freeText/>
        <hint/>
        <largeStorage>0</largeStorage>
        <multiSelect>0</multiSelect>
        <name>scope</name>
        <number>12</number>
        <picker>1</picker>
        <prettyName>scope</prettyName>
        <relationalStorage>0</relationalStorage>
        <separator> </separator>
        <separators>|, </separators>
        <size>1</size>
        <sort/>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <values>WIKI|SPACE|ALL_SPACES|WIKI+ALL_SPACES</values>
        <classType>com.xpn.xwiki.objects.classes.StaticListClass</classType>
      </scope>
      <sectionOrder>
        <customDisplay/>
        <disabled>0</disabled>
        <hint/>
        <name>sectionOrder</name>
        <number>12</number>
        <numberType>integer</numberType>
        <prettyName>sectionOrder</prettyName>
        <size>30</size>
        <unmodifiable>0</unmodifiable>
        <validationMessage/>
        <validationRegExp/>
        <classType>com.xpn.xwiki.objects.classes.NumberClass</classType>
      </sectionOrder>
    </class>
    <property>
      <categoryIcon>page_white_text</categoryIcon>
    </property>
    <property>
      <codeToExecute/>
    </property>
    <property>
      <configurationClass/>
    </property>
    <property>
      <displayBeforeCategory>edit</displayBeforeCategory>
    </property>
    <property>
      <displayInCategory>content</displayInCategory>
    </property>
    <property>
      <displayInSection>Templates</displayInSection>
    </property>
    <property>
      <heading/>
    </property>
    <property>
      <iconAttachment/>
    </property>
    <property>
      <linkPrefix/>
    </property>
    <property>
      <propertiesToShow/>
    </property>
    <property>
      <scope>WIKI</scope>
    </property>
    <property>
      <sectionOrder>100</sectionOrder>
    </property>
  </object>
</xwikidoc>

Output:
【漏洞类型】XSS（跨站脚本攻击）

【严重性】Medium

【漏洞摘要】这是一个XSS漏洞。具体表现为，原始代码在渲染提供者名称时，仅对$providerFullname进行了转义，但未对$providerFullname对应的文档标题（$xwiki.getDocument($providerFullname).plainTitle）进行二次转义。攻击者可以利用这一点，在$providerFullname中注入恶意脚本，当其他用户查看此列表时，恶意脚本会被执行。

【关键代码模式】
- 未进行二次转义的关键代码模式：$services.rendering.escape($xwiki.getDocument($providerFullname).plainTitle, $xwiki.currentContentSyntaxId)
- 关键函数：$services.rendering.escape
- 关键关键词：$xwiki.getDocument, $providerFullname

【修复方法说明】修复方法通过在$providerFullname中也进行转义，解决了XSS漏洞问题。最佳实践是确保所有用户输入和动态生成的内容在输出到网页之前都经过适当的转义处理，以防止潜在的XSS攻击。