1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-03-11 11:54:48 +01:00

Convert AphrontFormControl to safe HTML

Summary: Everything here now should properly handle plain strings and safe HTML.

Test Plan: /settings/panel/display/

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2432

Differential Revision: https://secure.phabricator.com/D4826
This commit is contained in:
vrana 2013-02-05 14:30:29 -08:00
parent be4662e667
commit 6bb7a282b1
20 changed files with 117 additions and 126 deletions

View file

@ -53,18 +53,16 @@ final class PhabricatorConduitConsoleController
} }
} }
$error_description = array();
$error_types = $method_object->defineErrorTypes(); $error_types = $method_object->defineErrorTypes();
if ($error_types) { if ($error_types) {
$error_description[] = '<ul>'; $error_description = array();
foreach ($error_types as $error => $meaning) { foreach ($error_types as $error => $meaning) {
$error_description[] = hsprintf( $error_description[] = hsprintf(
'<li><strong>%s:</strong> %s</li>', '<li><strong>%s:</strong> %s</li>',
$error, $error,
$meaning); $meaning);
} }
$error_description[] = '</ul>'; $error_description = phutil_tag('ul', array(), $error_description);
$error_description = implode("\n", $error_description);
} else { } else {
$error_description = "This method does not raise any specific errors."; $error_description = "This method does not raise any specific errors.";
} }

View file

@ -137,7 +137,7 @@ final class PhabricatorConfigEditController
array( array(
'class' => 'phabricator-remarkup', 'class' => 'phabricator-remarkup',
), ),
phutil_safe_html($engine->getOutput($option, 'description'))); $engine->getOutput($option, 'description'));
$form $form
->setUser($user) ->setUser($user)
@ -419,23 +419,23 @@ final class PhabricatorConfigEditController
} }
$table = array(); $table = array();
$table[] = '<tr class="column-labels">'; $table[] = hsprintf(
$table[] = '<th>'.pht('Example').'</th>'; '<tr class="column-labels"><th>%s</th><th>%s</th></tr>',
$table[] = '<th>'.pht('Value').'</th>'; pht('Example'),
$table[] = '</tr>'; pht('Value'));
foreach ($examples as $example) { foreach ($examples as $example) {
list($value, $description) = $example; list($value, $description) = $example;
if ($value === null) { if ($value === null) {
$value = '<em>'.pht('(empty)').'</em>'; $value = phutil_tag('em', array(), pht('(empty)'));
} else { } else {
$value = nl2br(phutil_escape_html($value)); $value = phutil_escape_html_newlines($value);
} }
$table[] = '<tr>'; $table[] = hsprintf(
$table[] = '<th>'.phutil_escape_html($description).'</th>'; '<tr><th>%s</th><td>%s</td></tr>',
$table[] = '<td>'.$value.'</td>'; $description,
$table[] = '</tr>'; $value);
} }
require_celerity_resource('config-options-css'); require_celerity_resource('config-options-css');
@ -445,7 +445,7 @@ final class PhabricatorConfigEditController
array( array(
'class' => 'config-option-table', 'class' => 'config-option-table',
), ),
new PhutilSafeHTML(implode("\n", $table))); $table);
} }
private function renderDefaults(PhabricatorConfigOption $option) { private function renderDefaults(PhabricatorConfigOption $option) {
@ -467,10 +467,10 @@ final class PhabricatorConfigEditController
$table = array(); $table = array();
$table[] = '<tr class="column-labels">'; $table[] = hsprintf(
$table[] = '<th>'.pht('Source').'</th>'; '<tr class="column-labels"><th>%s</th><th>%s</th></tr>',
$table[] = '<th>'.pht('Value').'</th>'; pht('Source'),
$table[] = '</tr>'; pht('Value'));
foreach ($stack as $key => $source) { foreach ($stack as $key => $source) {
$value = $source->getKeys( $value = $source->getKeys(
array( array(
@ -478,16 +478,16 @@ final class PhabricatorConfigEditController
)); ));
if (!array_key_exists($option->getKey(), $value)) { if (!array_key_exists($option->getKey(), $value)) {
$value = '<em>'.pht('(empty)').'</em>'; $value = phutil_tag('em', array(), pht('(empty)'));
} else { } else {
$value = PhabricatorConfigJSON::prettyPrintJSON( $value = PhabricatorConfigJSON::prettyPrintJSON(
$value[$option->getKey()]); $value[$option->getKey()]);
} }
$table[] = '<tr>'; $table[] = hsprintf(
$table[] = '<th>'.phutil_escape_html($source->getName()).'</th>'; '<tr><th>%s</th><td>%s</td></tr>',
$table[] = '<td>'.$value.'</td>'; $source->getName(),
$table[] = '</tr>'; $value);
} }
require_celerity_resource('config-options-css'); require_celerity_resource('config-options-css');
@ -497,7 +497,7 @@ final class PhabricatorConfigEditController
array( array(
'class' => 'config-option-table', 'class' => 'config-option-table',
), ),
new PhutilSafeHTML(implode("\n", $table))); $table);
} }
} }

View file

@ -38,11 +38,11 @@ final class DifferentialDiffViewController extends DifferentialController {
// TODO: implmenent optgroup support in AphrontFormSelectControl? // TODO: implmenent optgroup support in AphrontFormSelectControl?
$select = array(); $select = array();
$select[] = '<optgroup label="Create New Revision">'; $select[] = hsprintf('<optgroup label="%s">', pht('Create New Revision'));
$select[] = '<option value="">'. $select[] = hsprintf(
pht('Create a new Revision...'). '<option value="">%s</option>',
'</option>'; pht('Create a new Revision...'));
$select[] = '</optgroup>'; $select[] = hsprintf('</optgroup>');
$revision_data = new DifferentialRevisionListData( $revision_data = new DifferentialRevisionListData(
DifferentialRevisionListData::QUERY_OPEN_OWNED, DifferentialRevisionListData::QUERY_OPEN_OWNED,
@ -50,7 +50,9 @@ final class DifferentialDiffViewController extends DifferentialController {
$revisions = $revision_data->loadRevisions(); $revisions = $revision_data->loadRevisions();
if ($revisions) { if ($revisions) {
$select[] = '<optgroup label="'.pht('Update Existing Revision').'">'; $select[] = hsprintf(
'<optgroup label="%s">',
pht('Update Existing Revision'));
foreach ($revisions as $revision) { foreach ($revisions as $revision) {
$select[] = phutil_tag( $select[] = phutil_tag(
'option', 'option',
@ -59,13 +61,13 @@ final class DifferentialDiffViewController extends DifferentialController {
), ),
$revision->getTitle()); $revision->getTitle());
} }
$select[] = '</optgroup>'; $select[] = hsprintf('</optgroup>');
} }
$select = $select = phutil_tag(
'<select name="revisionID">'. 'select',
implode("\n", $select). array('name' => 'revisionID'),
'</select>'; $select);
$action_form = new AphrontFormView(); $action_form = new AphrontFormView();
$action_form $action_form

View file

@ -30,13 +30,12 @@ final class PhabricatorFileUploadController extends PhabricatorFileController {
$instructions = id(new AphrontFormMarkupControl()) $instructions = id(new AphrontFormMarkupControl())
->setControlID($support_id) ->setControlID($support_id)
->setControlStyle('display: none') ->setControlStyle('display: none')
->setValue( ->setValue(hsprintf(
'<br /><br />'. '<br /><br /><strong>%s</strong> %s<br /><br />',
pht('Drag and Drop:'),
pht( pht(
'<strong>Drag and Drop:</strong> You can also upload files by '. 'You can also upload files by dragging and dropping them from your '.
'dragging and dropping them from your desktop onto this page or '. 'desktop onto this page or the Phabricator home page.')));
'the Phabricator home page.').
'<br /><br />');
$form = id(new AphrontFormView()) $form = id(new AphrontFormView())
->setFlexible(true) ->setFlexible(true)

View file

@ -117,9 +117,10 @@ final class HeraldRuleController extends HeraldController {
$form $form
->appendChild( ->appendChild(
id(new AphrontFormMarkupControl()) id(new AphrontFormMarkupControl())
->setValue( ->setValue(hsprintf(
"This <strong>${rule_type_name}</strong> rule triggers for " . "This <strong>%s</strong> rule triggers for <strong>%s</strong>.",
"<strong>${content_type_name}</strong>.")) $rule_type_name,
$content_type_name)))
->appendChild( ->appendChild(
id(new AphrontFormInsetView()) id(new AphrontFormInsetView())
->setTitle('Conditions') ->setTitle('Conditions')
@ -154,9 +155,9 @@ final class HeraldRuleController extends HeraldController {
'mustcapture' => true, 'mustcapture' => true,
), ),
'Create New Action')) 'Create New Action'))
->setDescription( ->setDescription(hsprintf(
phutil_safe_html( 'Take these actions %s this rule matches:',
'Take these actions '.$repetition_selector.' this rule matches:')) $repetition_selector))
->setContent(javelin_tag( ->setContent(javelin_tag(
'table', 'table',
array( array(

View file

@ -455,11 +455,8 @@ final class ManiphestTaskEditController extends ManiphestController {
)); ));
if ($files) { if ($files) {
$file_display = array(); $file_display = mpull($files, 'getName');
foreach ($files as $file) { $file_display = array_interleave(phutil_tag('br'), $file_display);
$file_display[] = phutil_escape_html($file->getName());
}
$file_display = implode('<br />', $file_display);
$form->appendChild( $form->appendChild(
id(new AphrontFormMarkupControl()) id(new AphrontFormMarkupControl())

View file

@ -164,10 +164,9 @@ final class PhabricatorPasteEditController extends PhabricatorPasteController {
->appendChild( ->appendChild(
id(new AphrontFormMarkupControl()) id(new AphrontFormMarkupControl())
->setLabel('Text') ->setLabel('Text')
->setValue( ->setValue(hsprintf(
'Paste text can not be edited. '. 'Paste text can not be edited. %s to create a new paste.',
$fork_link.' to create a new paste.' $fork_link)));
));
} }
$submit = new AphrontFormSubmitControl(); $submit = new AphrontFormSubmitControl();

View file

@ -80,12 +80,7 @@ final class PhortuneMonthYearExpiryControl extends AphrontFormControl {
'sigil' => 'year-input', 'sigil' => 'year-input',
)); ));
return self::renderSingleView( return hsprintf('%s%s', $months_sel, $years_sel);
array(
$months_sel,
$years_sel
)
);
} }
} }

View file

@ -122,10 +122,10 @@ EXAMPLE;
->setValue($preferences->getPreference($pref_monospaced))) ->setValue($preferences->getPreference($pref_monospaced)))
->appendChild( ->appendChild(
id(new AphrontFormMarkupControl()) id(new AphrontFormMarkupControl())
->setValue( ->setValue(phutil_tag(
'<pre class="PhabricatorMonospaced">'. 'pre',
phutil_escape_html($example_string). array('class' => 'PhabricatorMonospaced'),
'</pre>')) $example_string)))
->appendChild( ->appendChild(
id(new AphrontFormRadioButtonControl()) id(new AphrontFormRadioButtonControl())
->setLabel('Monospaced Textareas') ->setLabel('Monospaced Textareas')

View file

@ -112,7 +112,6 @@ final class PhabricatorSlowvotePollController
$viewer_choices, $viewer_choices,
$option); $option);
} }
$option_markup = implode("\n", $option_markup);
$comments_by_option = array(); $comments_by_option = array();
switch ($poll->getMethod()) { switch ($poll->getMethod()) {

View file

@ -38,16 +38,15 @@ final class AphrontFormCheckboxControl extends AphrontFormControl {
'for' => $id, 'for' => $id,
), ),
$box['label']); $box['label']);
$rows[] = $rows[] = hsprintf(
'<tr>'. '<tr><td>%s</td><th>%s</th></tr>',
'<td>'.$checkbox.'</td>'. $checkbox,
'<th>'.$label.'</th>'. $label);
'</tr>';
} }
return return phutil_tag(
'<table class="aphront-form-control-checkbox-layout">'. 'table',
implode("\n", $rows). array('class' => 'aphront-form-control-checkbox-layout'),
'</table>'; $rows);
} }
} }

View file

@ -108,32 +108,32 @@ abstract class AphrontFormControl extends AphrontView {
$custom_class = $this->getCustomControlClass(); $custom_class = $this->getCustomControlClass();
if (strlen($this->getLabel())) { if (strlen($this->getLabel())) {
$label = $label = phutil_tag(
'<label class="aphront-form-label">'. 'label',
phutil_escape_html($this->getLabel()). array('class' => 'aphront-form-label'),
'</label>'; $this->getLabel());
} else { } else {
$label = null; $label = null;
$custom_class .= ' aphront-form-control-nolabel'; $custom_class .= ' aphront-form-control-nolabel';
} }
$input = $input = phutil_tag(
'<div class="aphront-form-input">'. 'div',
$this->renderInput(). array('class' => 'aphront-form-input'),
'</div>'; $this->renderInput());
if (strlen($this->getError())) { if (strlen($this->getError())) {
$error = $this->getError(); $error = $this->getError();
if ($error === true) { if ($error === true) {
$error = $error = phutil_tag(
'<div class="aphront-form-error aphront-form-required">'. 'div',
'Required'. array('class' => 'aphront-form-error aphront-form-required'),
'</div>'; 'Required');
} else { } else {
$error = $error = phutil_tag(
'<div class="aphront-form-error">'. 'div',
phutil_escape_html($error). array('class' => 'aphront-form-error'),
'</div>'; $error);
} }
} else { } else {
$error = null; $error = null;
@ -148,19 +148,21 @@ abstract class AphrontFormControl extends AphrontView {
$caption = null; $caption = null;
} }
return phutil_render_tag( return phutil_tag(
'div', 'div',
array( array(
'class' => "aphront-form-control {$custom_class}", 'class' => "aphront-form-control {$custom_class}",
'id' => $this->controlID, 'id' => $this->controlID,
'style' => $this->controlStyle, 'style' => $this->controlStyle,
), ),
$label. array(
$error. $label,
$input. $error,
$caption. $input,
$caption,
// TODO: Remove this once the redesign finishes up. // TODO: Remove this once the redesign finishes up.
'<div style="clear: both;"></div>'); phutil_tag('div', array('style' => 'clear: both;'), ''),
));
} }
} }

View file

@ -7,7 +7,7 @@ final class AphrontFormDividerControl extends AphrontFormControl {
} }
protected function renderInput() { protected function renderInput() {
return '<hr />'; return phutil_tag('hr');
} }
} }

View file

@ -9,14 +9,14 @@ final class AphrontFormImageControl extends AphrontFormControl {
protected function renderInput() { protected function renderInput() {
$id = celerity_generate_unique_node_id(); $id = celerity_generate_unique_node_id();
return return hsprintf(
'%s<div style="clear: both;">%s%s</div>',
phutil_tag( phutil_tag(
'input', 'input',
array( array(
'type' => 'file', 'type' => 'file',
'name' => $this->getName(), 'name' => $this->getName(),
)). )),
'<div style="clear: both;">'.
phutil_tag( phutil_tag(
'input', 'input',
array( array(
@ -24,14 +24,13 @@ final class AphrontFormImageControl extends AphrontFormControl {
'name' => 'default_image', 'name' => 'default_image',
'class' => 'default-image', 'class' => 'default-image',
'id' => $id, 'id' => $id,
)). )),
phutil_tag( phutil_tag(
'label', 'label',
array( array(
'for' => $id, 'for' => $id,
), ),
'Use Default Image instead'). 'Use Default Image instead'));
'</div>';
} }
} }

View file

@ -43,22 +43,21 @@ final class AphrontFormRadioButtonControl extends AphrontFormControl {
$button['label']); $button['label']);
if (strlen($button['caption'])) { if (strlen($button['caption'])) {
$label .= $label = hsprintf(
'<div class="aphront-form-radio-caption">'. '%s<div class="aphront-form-radio-caption">%s</div>',
phutil_escape_html($button['caption']). $label,
'</div>'; $button['caption']);
} }
$rows[] = $rows[] = hsprintf(
'<tr>'. '<tr><td>%s</td><th>%s</th></tr>',
'<td>'.$radio.'</td>'. $radio,
'<th>'.$label.'</th>'. $label);
'</tr>';
} }
return return phutil_tag(
'<table class="aphront-form-control-radio-layout">'. 'table',
implode("\n", $rows). array('class' => 'aphront-form-control-radio-layout'),
'</table>'; $rows);
} }
} }

View file

@ -53,10 +53,10 @@ final class AphrontFormRecaptchaControl extends AphrontFormControl {
$protocol = $uri->getProtocol(); $protocol = $uri->getProtocol();
$use_ssl = ($protocol == 'https'); $use_ssl = ($protocol == 'https');
return recaptcha_get_html( return phutil_safe_html(recaptcha_get_html(
PhabricatorEnv::getEnvConfig('recaptcha.public-key'), PhabricatorEnv::getEnvConfig('recaptcha.public-key'),
$error = null, $error = null,
$use_ssl); $use_ssl));
} }
} }

View file

@ -7,7 +7,7 @@ final class AphrontFormStaticControl extends AphrontFormControl {
} }
protected function renderInput() { protected function renderInput() {
return phutil_escape_html($this->getValue()); return $this->getValue();
} }
} }

View file

@ -30,7 +30,7 @@ final class AphrontFormSubmitControl extends AphrontFormControl {
), ),
$this->getValue()); $this->getValue());
} }
return $submit_button.$this->cancelButton; return hsprintf('%s%s', $submit_button, $this->cancelButton);
} }
} }

View file

@ -46,7 +46,7 @@ final class AphrontFormToggleButtonsControl extends AphrontFormControl {
$label); $label);
} }
return implode('', $out); return $out;
} }
} }

View file

@ -2,10 +2,12 @@
final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl {
private $disableMacro = false; private $disableMacro = false;
public function setDisableMacros($disable) { public function setDisableMacros($disable) {
$this->disableMacro = $disable; $this->disableMacro = $disable;
return $this; return $this;
} }
protected function renderInput() { protected function renderInput() {
$id = $this->getID(); $id = $this->getID();
if (!$id) { if (!$id) {