Repository navigation
Add protection from some network issues #107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
f568032
8923d38
22f9869
8fb21b0
741903b
84e29e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -160,28 +160,28 @@ void PVStructureArray::deserialize(ByteBuffer *pbuffer, | |
| DeserializableControl *pcontrol) { | ||
| svector data(reuse()); | ||
|
anjohnson marked this conversation as resolved.
|
||
|
|
||
| size_t size = this->getArray()->getArraySizeType() == Array::fixed ? | ||
| this->getArray()->getMaximumCapacity() : | ||
| SerializeHelper::readSize(pbuffer, pcontrol); | ||
|
|
||
| data.resize(size); | ||
| const size_t size = this->getArray()->getArraySizeType() == Array::fixed ? | ||
| this->getArray()->getMaximumCapacity() : | ||
| SerializeHelper::readSize(pbuffer, pcontrol); | ||
|
|
||
| StructureConstPtr structure = structureArray->getStructure(); | ||
|
|
||
| PVDataCreatePtr pvDataCreate = getPVDataCreate(); | ||
|
|
||
| // Don't trust 'size' for new or larger arrays, start | ||
| // small and grow them as elements are deserialized. | ||
| data.resize(0); | ||
| data.reserve(size < 64 ? size : 64); | ||
|
Comment on lines
+173
to
+174
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude Sonnet 5: The old per-element reuse optimization (reuse still-unique PVStructure/PVUnion objects across deserialize calls) is silently discarded.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The Subsequent monitor updates should re-use the array storage where the attribute list doesn't change, but some experiments may continue to add attributes over time, and those would be the ones I worry about.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
A reuse() is attempted because it is low cost. However, I think it is unlikely to succeed in the most important cases (AD). It would be unlikely in the case of a QSRV1 group mapping as a reference to the most recent value is kept. I worry that this attempt to "harden" against a malicious peer will unduly harm performance on all others. So I am going to hold off on this part until the core developer group agrees on a policy on regarding DoS mitigations which negatively impact performance. |
||
| for(size_t i = 0; i<size; i++) { | ||
| pcontrol->ensureData(1); | ||
| size_t temp = pbuffer->getByte(); | ||
| if(temp==0) { | ||
| data[i].reset(); | ||
| } | ||
| else { | ||
| if(data[i].get()==NULL || !data[i].unique()) { | ||
| data[i] = pvDataCreate->createPVStructure(structure); | ||
| } | ||
| data[i]->deserialize(pbuffer, pcontrol); | ||
|
|
||
| PVStructurePtr pvStructure; | ||
| if(temp!=0) { | ||
| pvStructure = pvDataCreate->createPVStructure(structure); | ||
| pvStructure->deserialize(pbuffer, pcontrol); | ||
| } | ||
| data.push_back(pvStructure); | ||
| } | ||
| replace(freeze(data)); // calls postPut() | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -158,21 +158,26 @@ void PVUnion::deserialize(ByteBuffer *pbuffer, DeserializableControl *pcontrol) | |
| } | ||
| else | ||
| { | ||
| int32 previousSelector = selector; | ||
| selector = static_cast<int32>(SerializeHelper::readSize(pbuffer, pcontrol)); | ||
| if (selector != UNDEFINED_INDEX) | ||
| int32 index = static_cast<int32>(SerializeHelper::readSize(pbuffer, pcontrol)); | ||
| if (index == UNDEFINED_INDEX) | ||
| { | ||
| if (selector != previousSelector) | ||
| selector = index; | ||
| value.reset(); | ||
| } | ||
| else if (index < 0 || size_t(index) >= unionPtr->getFields().size()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This check is redundant to the later |
||
| throw std::runtime_error("union index out of bounds"); | ||
| else | ||
| { | ||
| if (selector != index) | ||
| { | ||
| FieldConstPtr field = unionPtr->getField(selector); | ||
| selector = index; | ||
| FieldConstPtr field = unionPtr->getField(index); | ||
| // try to reuse existing field instance | ||
| if (!value.get() || *value->getField() != *field) | ||
| value = pvDataCreate->createPVField(field); | ||
| } | ||
| value->deserialize(pbuffer, pcontrol); | ||
| } | ||
| else | ||
| value.reset(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,7 +50,7 @@ namespace epics { | |
| * | ||
| * @param[in] buffer deserialization buffer. | ||
| * @param[in] control the DeserializableControl. | ||
| * @returns array size. | ||
| * @returns array size, or (size_t) -1. | ||
| */ | ||
| static std::size_t readSize(ByteBuffer* buffer, | ||
| DeserializableControl* control); | ||
|
|
@@ -80,20 +80,18 @@ namespace epics { | |
|
|
||
| /** | ||
| * std::string deserialization helper method. | ||
| * TODO This method cannot return "null", but Java implementation | ||
| * could have serialized "null" value as well. We need to decide | ||
| * how to deserialize "null". | ||
| * | ||
| * @param[in] buffer deserialization buffer | ||
| * @param[in] control control | ||
| * @param[in] max length limit | ||
| * @returns deserialized string | ||
| * | ||
| * @todo This method cannot return "null", but Java implementation | ||
| * could have serialized "null" value as well. We need to decide | ||
| * how to deserialize "null". | ||
| * could have serialized "null" value as well. This implementation | ||
| * returns an empty string in that event. | ||
| */ | ||
| static std::string deserializeString(ByteBuffer* buffer, | ||
| DeserializableControl* control); | ||
| DeserializableControl* control, std::size_t max = INT32_MAX); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No objection to the added argument. I have a small concern about whether the |
||
|
|
||
| private: | ||
| SerializeHelper() {}; | ||
|
|
@@ -112,4 +110,6 @@ namespace epics { | |
| } | ||
| } | ||
|
|
||
| #define DESERIALIZE_STRING_HAS_LIMIT | ||
|
|
||
| #endif /* SERIALIZEHELPER_H_ */ | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -72,6 +72,14 @@ void Status::deserialize(ByteBuffer *buffer, DeserializableControl *flusher) | |
| m_stackDump.clear(); | ||
| } | ||
| } | ||
| else if (typeCode < 0 || typeCode > STATUSTYPE_FATAL) | ||
| { | ||
| // Leave *this as fatal and throw | ||
| m_statusType = STATUSTYPE_FATAL; | ||
| m_message = "deserialized type code was invalid"; | ||
| m_stackDump.clear(); | ||
| THROW_BASE_EXCEPTION("invalid Status type code"); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While I do not see much chance that we will want to add codes in future, it seems unnecessary to close the door on this possibility now. I will instead treat all currently unknown codes as FATAL. |
||
| } | ||
| else | ||
| { | ||
| m_statusType = (StatusType)typeCode; | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.