@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

vrana 6bb7a282 be4662e6

+117 -126
+2 -4
src/applications/conduit/controller/PhabricatorConduitConsoleController.php
··· 53 53 } 54 54 } 55 55 56 - $error_description = array(); 57 56 $error_types = $method_object->defineErrorTypes(); 58 57 if ($error_types) { 59 - $error_description[] = '<ul>'; 58 + $error_description = array(); 60 59 foreach ($error_types as $error => $meaning) { 61 60 $error_description[] = hsprintf( 62 61 '<li><strong>%s:</strong> %s</li>', 63 62 $error, 64 63 $meaning); 65 64 } 66 - $error_description[] = '</ul>'; 67 - $error_description = implode("\n", $error_description); 65 + $error_description = phutil_tag('ul', array(), $error_description); 68 66 } else { 69 67 $error_description = "This method does not raise any specific errors."; 70 68 }
+22 -22
src/applications/config/controller/PhabricatorConfigEditController.php
··· 137 137 array( 138 138 'class' => 'phabricator-remarkup', 139 139 ), 140 - phutil_safe_html($engine->getOutput($option, 'description'))); 140 + $engine->getOutput($option, 'description')); 141 141 142 142 $form 143 143 ->setUser($user) ··· 419 419 } 420 420 421 421 $table = array(); 422 - $table[] = '<tr class="column-labels">'; 423 - $table[] = '<th>'.pht('Example').'</th>'; 424 - $table[] = '<th>'.pht('Value').'</th>'; 425 - $table[] = '</tr>'; 422 + $table[] = hsprintf( 423 + '<tr class="column-labels"><th>%s</th><th>%s</th></tr>', 424 + pht('Example'), 425 + pht('Value')); 426 426 foreach ($examples as $example) { 427 427 list($value, $description) = $example; 428 428 429 429 if ($value === null) { 430 - $value = '<em>'.pht('(empty)').'</em>'; 430 + $value = phutil_tag('em', array(), pht('(empty)')); 431 431 } else { 432 - $value = nl2br(phutil_escape_html($value)); 432 + $value = phutil_escape_html_newlines($value); 433 433 } 434 434 435 - $table[] = '<tr>'; 436 - $table[] = '<th>'.phutil_escape_html($description).'</th>'; 437 - $table[] = '<td>'.$value.'</td>'; 438 - $table[] = '</tr>'; 435 + $table[] = hsprintf( 436 + '<tr><th>%s</th><td>%s</td></tr>', 437 + $description, 438 + $value); 439 439 } 440 440 441 441 require_celerity_resource('config-options-css'); ··· 445 445 array( 446 446 'class' => 'config-option-table', 447 447 ), 448 - new PhutilSafeHTML(implode("\n", $table))); 448 + $table); 449 449 } 450 450 451 451 private function renderDefaults(PhabricatorConfigOption $option) { ··· 467 467 468 468 469 469 $table = array(); 470 - $table[] = '<tr class="column-labels">'; 471 - $table[] = '<th>'.pht('Source').'</th>'; 472 - $table[] = '<th>'.pht('Value').'</th>'; 473 - $table[] = '</tr>'; 470 + $table[] = hsprintf( 471 + '<tr class="column-labels"><th>%s</th><th>%s</th></tr>', 472 + pht('Source'), 473 + pht('Value')); 474 474 foreach ($stack as $key => $source) { 475 475 $value = $source->getKeys( 476 476 array( ··· 478 478 )); 479 479 480 480 if (!array_key_exists($option->getKey(), $value)) { 481 - $value = '<em>'.pht('(empty)').'</em>'; 481 + $value = phutil_tag('em', array(), pht('(empty)')); 482 482 } else { 483 483 $value = PhabricatorConfigJSON::prettyPrintJSON( 484 484 $value[$option->getKey()]); 485 485 } 486 486 487 - $table[] = '<tr>'; 488 - $table[] = '<th>'.phutil_escape_html($source->getName()).'</th>'; 489 - $table[] = '<td>'.$value.'</td>'; 490 - $table[] = '</tr>'; 487 + $table[] = hsprintf( 488 + '<tr><th>%s</th><td>%s</td></tr>', 489 + $source->getName(), 490 + $value); 491 491 } 492 492 493 493 require_celerity_resource('config-options-css'); ··· 497 497 array( 498 498 'class' => 'config-option-table', 499 499 ), 500 - new PhutilSafeHTML(implode("\n", $table))); 500 + $table); 501 501 } 502 502 503 503 }
+13 -11
src/applications/differential/controller/DifferentialDiffViewController.php
··· 38 38 39 39 // TODO: implmenent optgroup support in AphrontFormSelectControl? 40 40 $select = array(); 41 - $select[] = '<optgroup label="Create New Revision">'; 42 - $select[] = '<option value="">'. 43 - pht('Create a new Revision...'). 44 - '</option>'; 45 - $select[] = '</optgroup>'; 41 + $select[] = hsprintf('<optgroup label="%s">', pht('Create New Revision')); 42 + $select[] = hsprintf( 43 + '<option value="">%s</option>', 44 + pht('Create a new Revision...')); 45 + $select[] = hsprintf('</optgroup>'); 46 46 47 47 $revision_data = new DifferentialRevisionListData( 48 48 DifferentialRevisionListData::QUERY_OPEN_OWNED, ··· 50 50 $revisions = $revision_data->loadRevisions(); 51 51 52 52 if ($revisions) { 53 - $select[] = '<optgroup label="'.pht('Update Existing Revision').'">'; 53 + $select[] = hsprintf( 54 + '<optgroup label="%s">', 55 + pht('Update Existing Revision')); 54 56 foreach ($revisions as $revision) { 55 57 $select[] = phutil_tag( 56 58 'option', ··· 59 61 ), 60 62 $revision->getTitle()); 61 63 } 62 - $select[] = '</optgroup>'; 64 + $select[] = hsprintf('</optgroup>'); 63 65 } 64 66 65 - $select = 66 - '<select name="revisionID">'. 67 - implode("\n", $select). 68 - '</select>'; 67 + $select = phutil_tag( 68 + 'select', 69 + array('name' => 'revisionID'), 70 + $select); 69 71 70 72 $action_form = new AphrontFormView(); 71 73 $action_form
+5 -6
src/applications/files/controller/PhabricatorFileUploadController.php
··· 30 30 $instructions = id(new AphrontFormMarkupControl()) 31 31 ->setControlID($support_id) 32 32 ->setControlStyle('display: none') 33 - ->setValue( 34 - '<br /><br />'. 33 + ->setValue(hsprintf( 34 + '<br /><br /><strong>%s</strong> %s<br /><br />', 35 + pht('Drag and Drop:'), 35 36 pht( 36 - '<strong>Drag and Drop:</strong> You can also upload files by '. 37 - 'dragging and dropping them from your desktop onto this page or '. 38 - 'the Phabricator home page.'). 39 - '<br /><br />'); 37 + 'You can also upload files by dragging and dropping them from your '. 38 + 'desktop onto this page or the Phabricator home page.'))); 40 39 41 40 $form = id(new AphrontFormView()) 42 41 ->setFlexible(true)
+7 -6
src/applications/herald/controller/HeraldRuleController.php
··· 117 117 $form 118 118 ->appendChild( 119 119 id(new AphrontFormMarkupControl()) 120 - ->setValue( 121 - "This <strong>${rule_type_name}</strong> rule triggers for " . 122 - "<strong>${content_type_name}</strong>.")) 120 + ->setValue(hsprintf( 121 + "This <strong>%s</strong> rule triggers for <strong>%s</strong>.", 122 + $rule_type_name, 123 + $content_type_name))) 123 124 ->appendChild( 124 125 id(new AphrontFormInsetView()) 125 126 ->setTitle('Conditions') ··· 154 155 'mustcapture' => true, 155 156 ), 156 157 'Create New Action')) 157 - ->setDescription( 158 - phutil_safe_html( 159 - 'Take these actions '.$repetition_selector.' this rule matches:')) 158 + ->setDescription(hsprintf( 159 + 'Take these actions %s this rule matches:', 160 + $repetition_selector)) 160 161 ->setContent(javelin_tag( 161 162 'table', 162 163 array(
+2 -5
src/applications/maniphest/controller/ManiphestTaskEditController.php
··· 455 455 )); 456 456 457 457 if ($files) { 458 - $file_display = array(); 459 - foreach ($files as $file) { 460 - $file_display[] = phutil_escape_html($file->getName()); 461 - } 462 - $file_display = implode('<br />', $file_display); 458 + $file_display = mpull($files, 'getName'); 459 + $file_display = array_interleave(phutil_tag('br'), $file_display); 463 460 464 461 $form->appendChild( 465 462 id(new AphrontFormMarkupControl())
+3 -4
src/applications/paste/controller/PhabricatorPasteEditController.php
··· 164 164 ->appendChild( 165 165 id(new AphrontFormMarkupControl()) 166 166 ->setLabel('Text') 167 - ->setValue( 168 - 'Paste text can not be edited. '. 169 - $fork_link.' to create a new paste.' 170 - )); 167 + ->setValue(hsprintf( 168 + 'Paste text can not be edited. %s to create a new paste.', 169 + $fork_link))); 171 170 } 172 171 173 172 $submit = new AphrontFormSubmitControl();
+1 -6
src/applications/phortune/control/PhortuneMonthYearExpiryControl.php
··· 80 80 'sigil' => 'year-input', 81 81 )); 82 82 83 - return self::renderSingleView( 84 - array( 85 - $months_sel, 86 - $years_sel 87 - ) 88 - ); 83 + return hsprintf('%s%s', $months_sel, $years_sel); 89 84 } 90 85 91 86 }
+4 -4
src/applications/settings/panel/PhabricatorSettingsPanelDisplayPreferences.php
··· 122 122 ->setValue($preferences->getPreference($pref_monospaced))) 123 123 ->appendChild( 124 124 id(new AphrontFormMarkupControl()) 125 - ->setValue( 126 - '<pre class="PhabricatorMonospaced">'. 127 - phutil_escape_html($example_string). 128 - '</pre>')) 125 + ->setValue(phutil_tag( 126 + 'pre', 127 + array('class' => 'PhabricatorMonospaced'), 128 + $example_string))) 129 129 ->appendChild( 130 130 id(new AphrontFormRadioButtonControl()) 131 131 ->setLabel('Monospaced Textareas')
-1
src/applications/slowvote/controller/PhabricatorSlowvotePollController.php
··· 112 112 $viewer_choices, 113 113 $option); 114 114 } 115 - $option_markup = implode("\n", $option_markup); 116 115 117 116 $comments_by_option = array(); 118 117 switch ($poll->getMethod()) {
+8 -9
src/view/form/control/AphrontFormCheckboxControl.php
··· 38 38 'for' => $id, 39 39 ), 40 40 $box['label']); 41 - $rows[] = 42 - '<tr>'. 43 - '<td>'.$checkbox.'</td>'. 44 - '<th>'.$label.'</th>'. 45 - '</tr>'; 41 + $rows[] = hsprintf( 42 + '<tr><td>%s</td><th>%s</th></tr>', 43 + $checkbox, 44 + $label); 46 45 } 47 - return 48 - '<table class="aphront-form-control-checkbox-layout">'. 49 - implode("\n", $rows). 50 - '</table>'; 46 + return phutil_tag( 47 + 'table', 48 + array('class' => 'aphront-form-control-checkbox-layout'), 49 + $rows); 51 50 } 52 51 53 52 }
+25 -23
src/view/form/control/AphrontFormControl.php
··· 108 108 $custom_class = $this->getCustomControlClass(); 109 109 110 110 if (strlen($this->getLabel())) { 111 - $label = 112 - '<label class="aphront-form-label">'. 113 - phutil_escape_html($this->getLabel()). 114 - '</label>'; 111 + $label = phutil_tag( 112 + 'label', 113 + array('class' => 'aphront-form-label'), 114 + $this->getLabel()); 115 115 } else { 116 116 $label = null; 117 117 $custom_class .= ' aphront-form-control-nolabel'; 118 118 } 119 119 120 - $input = 121 - '<div class="aphront-form-input">'. 122 - $this->renderInput(). 123 - '</div>'; 120 + $input = phutil_tag( 121 + 'div', 122 + array('class' => 'aphront-form-input'), 123 + $this->renderInput()); 124 124 125 125 if (strlen($this->getError())) { 126 126 $error = $this->getError(); 127 127 if ($error === true) { 128 - $error = 129 - '<div class="aphront-form-error aphront-form-required">'. 130 - 'Required'. 131 - '</div>'; 128 + $error = phutil_tag( 129 + 'div', 130 + array('class' => 'aphront-form-error aphront-form-required'), 131 + 'Required'); 132 132 } else { 133 - $error = 134 - '<div class="aphront-form-error">'. 135 - phutil_escape_html($error). 136 - '</div>'; 133 + $error = phutil_tag( 134 + 'div', 135 + array('class' => 'aphront-form-error'), 136 + $error); 137 137 } 138 138 } else { 139 139 $error = null; ··· 148 148 $caption = null; 149 149 } 150 150 151 - return phutil_render_tag( 151 + return phutil_tag( 152 152 'div', 153 153 array( 154 154 'class' => "aphront-form-control {$custom_class}", 155 155 'id' => $this->controlID, 156 156 'style' => $this->controlStyle, 157 157 ), 158 - $label. 159 - $error. 160 - $input. 161 - $caption. 158 + array( 159 + $label, 160 + $error, 161 + $input, 162 + $caption, 162 163 163 - // TODO: Remove this once the redesign finishes up. 164 - '<div style="clear: both;"></div>'); 164 + // TODO: Remove this once the redesign finishes up. 165 + phutil_tag('div', array('style' => 'clear: both;'), ''), 166 + )); 165 167 } 166 168 }
+1 -1
src/view/form/control/AphrontFormDividerControl.php
··· 7 7 } 8 8 9 9 protected function renderInput() { 10 - return '<hr />'; 10 + return phutil_tag('hr'); 11 11 } 12 12 13 13 }
+5 -6
src/view/form/control/AphrontFormImageControl.php
··· 9 9 protected function renderInput() { 10 10 $id = celerity_generate_unique_node_id(); 11 11 12 - return 12 + return hsprintf( 13 + '%s<div style="clear: both;">%s%s</div>', 13 14 phutil_tag( 14 15 'input', 15 16 array( 16 17 'type' => 'file', 17 18 'name' => $this->getName(), 18 - )). 19 - '<div style="clear: both;">'. 19 + )), 20 20 phutil_tag( 21 21 'input', 22 22 array( ··· 24 24 'name' => 'default_image', 25 25 'class' => 'default-image', 26 26 'id' => $id, 27 - )). 27 + )), 28 28 phutil_tag( 29 29 'label', 30 30 array( 31 31 'for' => $id, 32 32 ), 33 - 'Use Default Image instead'). 34 - '</div>'; 33 + 'Use Default Image instead')); 35 34 } 36 35 37 36 }
+12 -13
src/view/form/control/AphrontFormRadioButtonControl.php
··· 43 43 $button['label']); 44 44 45 45 if (strlen($button['caption'])) { 46 - $label .= 47 - '<div class="aphront-form-radio-caption">'. 48 - phutil_escape_html($button['caption']). 49 - '</div>'; 46 + $label = hsprintf( 47 + '%s<div class="aphront-form-radio-caption">%s</div>', 48 + $label, 49 + $button['caption']); 50 50 } 51 - $rows[] = 52 - '<tr>'. 53 - '<td>'.$radio.'</td>'. 54 - '<th>'.$label.'</th>'. 55 - '</tr>'; 51 + $rows[] = hsprintf( 52 + '<tr><td>%s</td><th>%s</th></tr>', 53 + $radio, 54 + $label); 56 55 } 57 56 58 - return 59 - '<table class="aphront-form-control-radio-layout">'. 60 - implode("\n", $rows). 61 - '</table>'; 57 + return phutil_tag( 58 + 'table', 59 + array('class' => 'aphront-form-control-radio-layout'), 60 + $rows); 62 61 } 63 62 64 63 }
+2 -2
src/view/form/control/AphrontFormRecaptchaControl.php
··· 53 53 $protocol = $uri->getProtocol(); 54 54 $use_ssl = ($protocol == 'https'); 55 55 56 - return recaptcha_get_html( 56 + return phutil_safe_html(recaptcha_get_html( 57 57 PhabricatorEnv::getEnvConfig('recaptcha.public-key'), 58 58 $error = null, 59 - $use_ssl); 59 + $use_ssl)); 60 60 } 61 61 62 62 }
+1 -1
src/view/form/control/AphrontFormStaticControl.php
··· 7 7 } 8 8 9 9 protected function renderInput() { 10 - return phutil_escape_html($this->getValue()); 10 + return $this->getValue(); 11 11 } 12 12 13 13 }
+1 -1
src/view/form/control/AphrontFormSubmitControl.php
··· 30 30 ), 31 31 $this->getValue()); 32 32 } 33 - return $submit_button.$this->cancelButton; 33 + return hsprintf('%s%s', $submit_button, $this->cancelButton); 34 34 } 35 35 36 36 }
+1 -1
src/view/form/control/AphrontFormToggleButtonsControl.php
··· 46 46 $label); 47 47 } 48 48 49 - return implode('', $out); 49 + return $out; 50 50 } 51 51 52 52 }
+2
src/view/form/control/PhabricatorRemarkupControl.php
··· 2 2 3 3 final class PhabricatorRemarkupControl extends AphrontFormTextAreaControl { 4 4 private $disableMacro = false; 5 + 5 6 public function setDisableMacros($disable) { 6 7 $this->disableMacro = $disable; 7 8 return $this; 8 9 } 10 + 9 11 protected function renderInput() { 10 12 $id = $this->getID(); 11 13 if (!$id) {