Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15397847
D13939.id33647.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
D13939.id33647.diff
View Options
diff --git a/src/applications/audit/editor/PhabricatorAuditEditor.php b/src/applications/audit/editor/PhabricatorAuditEditor.php
--- a/src/applications/audit/editor/PhabricatorAuditEditor.php
+++ b/src/applications/audit/editor/PhabricatorAuditEditor.php
@@ -949,6 +949,12 @@
);
}
+ protected function getCustomWorkerStateEncoding() {
+ return array(
+ 'rawPatch' => self::STORAGE_ENCODING_BINARY,
+ );
+ }
+
protected function loadCustomWorkerState(array $state) {
$this->rawPatch = idx($state, 'rawPatch');
$this->affectedFiles = idx($state, 'affectedFiles');
diff --git a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
--- a/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
+++ b/src/applications/transactions/editor/PhabricatorApplicationTransactionEditor.php
@@ -69,6 +69,8 @@
private $feedNotifyPHIDs = array();
private $feedRelatedPHIDs = array();
+ const STORAGE_ENCODING_BINARY = 'binary';
+
/**
* Get the class name for the application this editor is a part of.
*
@@ -2637,6 +2639,21 @@
}
+ /**
+ * @task mail
+ */
+ private function runHeraldMailRules(array $messages) {
+ foreach ($messages as $message) {
+ $engine = new HeraldEngine();
+ $adapter = id(new PhabricatorMailOutboundMailHeraldAdapter())
+ ->setObject($message);
+
+ $rules = $engine->loadRulesForAdapter($adapter);
+ $effects = $engine->applyRules($rules, $adapter);
+ $engine->applyEffects($effects, $adapter, $rules);
+ }
+ }
+
/* -( Publishing Feed Stories )-------------------------------------------- */
@@ -3060,9 +3077,13 @@
$state[$property] = $this->$property;
}
+ $custom_state = $this->getCustomWorkerState();
+ $custom_encoding = $this->getCustomWorkerStateEncoding();
+
$state += array(
'excludeMailRecipientPHIDs' => $this->getExcludeMailRecipientPHIDs(),
- 'custom' => $this->getCustomWorkerState(),
+ 'custom' => $this->encodeStateForStorage($custom_state, $custom_encoding),
+ 'custom.encoding' => $custom_encoding,
);
return $state;
@@ -3081,6 +3102,21 @@
/**
+ * Hook; return storage encoding for custom properties which need to be
+ * passed to workers.
+ *
+ * This primarily allows binary data to be passed to workers and survive
+ * JSON encoding.
+ *
+ * @return dict<string, string> Property encodings.
+ * @task workers
+ */
+ protected function getCustomWorkerStateEncoding() {
+ return array();
+ }
+
+
+ /**
* Load editor state using a dictionary emitted by @{method:getWorkerState}.
*
* This method is used to load state when running worker operations.
@@ -3097,7 +3133,10 @@
$exclude = idx($state, 'excludeMailRecipientPHIDs', array());
$this->setExcludeMailRecipientPHIDs($exclude);
- $custom = idx($state, 'custom', array());
+ $custom_state = idx($state, 'custom', array());
+ $custom_encodings = idx($state, 'custom.encoding', array());
+ $custom = $this->decodeStateFromStorage($custom_state, $custom_encodings);
+
$this->loadCustomWorkerState($custom);
return $this;
@@ -3143,16 +3182,85 @@
);
}
- private function runHeraldMailRules(array $messages) {
- foreach ($messages as $message) {
- $engine = new HeraldEngine();
- $adapter = id(new PhabricatorMailOutboundMailHeraldAdapter())
- ->setObject($message);
+ /**
+ * Apply encodings prior to storage.
+ *
+ * See @{method:getCustomWorkerStateEncoding}.
+ *
+ * @param map<string, wild> Map of values to encode.
+ * @param map<string, string> Map of encodings to apply.
+ * @return map<string, wild> Map of encoded values.
+ * @task workers
+ */
+ final private function encodeStateForStorage(
+ array $state,
+ array $encodings) {
+
+ foreach ($state as $key => $value) {
+ $encoding = idx($encodings, $key);
+ switch ($encoding) {
+ case self::STORAGE_ENCODING_BINARY:
+ // The mechanics of this encoding (serialize + base64) are a little
+ // awkward, but it allows us encode arrays and still be JSON-safe
+ // with binary data.
+
+ $value = @serialize($value);
+ if ($value === false) {
+ throw new Exception(
+ pht(
+ 'Failed to serialize() value for key "%s".',
+ $key));
+ }
- $rules = $engine->loadRulesForAdapter($adapter);
- $effects = $engine->applyRules($rules, $adapter);
- $engine->applyEffects($effects, $adapter, $rules);
+ $value = base64_encode($value);
+ if ($value === false) {
+ throw new Exception(
+ pht(
+ 'Failed to base64 encode value for key "%s".',
+ $key));
+ }
+ break;
+ }
+ $state[$key] = $value;
}
+
+ return $state;
+ }
+
+
+ /**
+ * Undo storage encoding applied when storing state.
+ *
+ * See @{method:getCustomWorkerStateEncoding}.
+ *
+ * @param map<string, wild> Map of encoded values.
+ * @param map<string, string> Map of encodings.
+ * @return map<string, wild> Map of decoded values.
+ * @task workers
+ */
+ final private function decodeStateFromStorage(
+ array $state,
+ array $encodings) {
+
+ foreach ($state as $key => $value) {
+ $encoding = idx($encodings, $key);
+ switch ($encoding) {
+ case self::STORAGE_ENCODING_BINARY:
+ $value = base64_decode($value);
+ if ($value === false) {
+ throw new Exception(
+ pht(
+ 'Failed to base64_decode() value for key "%s".',
+ $key));
+ }
+
+ $value = unserialize($value);
+ break;
+ }
+ $state[$key] = $value;
+ }
+
+ return $state;
}
}
diff --git a/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php b/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php
--- a/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php
+++ b/src/applications/transactions/worker/PhabricatorApplicationTransactionPublishWorker.php
@@ -26,9 +26,14 @@
* Load the object the transactions affect.
*/
private function loadObject() {
- $data = $this->getTaskData();
$viewer = PhabricatorUser::getOmnipotentUser();
+ $data = $this->getTaskData();
+ if (!is_array($data)) {
+ throw new PhabricatorWorkerPermanentFailureException(
+ pht('Task has invalid task data.'));
+ }
+
$phid = idx($data, 'objectPHID');
if (!$phid) {
throw new PhabricatorWorkerPermanentFailureException(
diff --git a/src/infrastructure/storage/lisk/LiskDAO.php b/src/infrastructure/storage/lisk/LiskDAO.php
--- a/src/infrastructure/storage/lisk/LiskDAO.php
+++ b/src/infrastructure/storage/lisk/LiskDAO.php
@@ -1651,7 +1651,7 @@
if ($deserialize) {
$data[$col] = json_decode($data[$col], true);
} else {
- $data[$col] = json_encode($data[$col]);
+ $data[$col] = phutil_json_encode($data[$col]);
}
break;
default:
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Mar 17, 10:36 PM (22 h, 28 m ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7385844
Default Alt Text
D13939.id33647.diff (7 KB)
Attached To
Mode
D13939: Allow transaction publishers to pass binary data to workers
Attached
Detach File
Event Timeline
Log In to Comment