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
[4.x.x] Improve out-of-scope detection for binary variables #4408
[4.x.x] Improve out-of-scope detection for binary variables #4408
Conversation
…n the returned Context Sequence (i.e. still in-scope)
0f91ae5
to
1e031d7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some minor suggestions... ;-)
exist-core/src/main/java/org/exist/xquery/value/SubSequence.java
Outdated
Show resolved
Hide resolved
exist-core/src/main/java/org/exist/xquery/value/SubSequence.java
Outdated
Show resolved
Hide resolved
for (final Mapping mapping : this.mappings) { | ||
for (int i = 0; i < this.mappings.size(); i++) { | ||
final Mapping mapping = this.mappings.get(i); | ||
if (i > 0) { | ||
dumper.display(", "); | ||
} | ||
mapping.key.dump(dumper); | ||
dumper.display(" := "); | ||
dumper.display(" : "); | ||
mapping.value.dump(dumper); | ||
} | ||
dumper.display("}"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could imagine using a single boolean would remove the total amount of additional calls eventually:
boolean firstMapping = true;
for (final Mapping mapping : this.mappings) {
mapping.key.dump(dumper);
dumper.display(" := ");
dumper.display(" : ");
mapping.value.dump(dumper);
if (firstMapping) {
firstMapping = false;
} else {
dumper.display(", ");
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I am not mistaken you code will end up with a trailing ,
as it postfixes with the comma character, whereas my code prefixes with the comma character to ensure no "dangling" comma.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @adamretter , the if/else block should of course go prior the key/value rendering:
boolean firstMapping = true;
for (final Mapping mapping : this.mappings) {
if (firstMapping) {
firstMapping = false;
} else {
dumper.display(", ");
}
mapping.key.dump(dumper);
dumper.display(" := ");
dumper.display(" : ");
mapping.value.dump(dumper);
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found some spots, that may need a second look....
exist-core/src/main/java/org/exist/xquery/functions/map/MapType.java
Outdated
Show resolved
Hide resolved
exist-core/src/main/java/org/exist/xquery/functions/map/MapType.java
Outdated
Show resolved
Hide resolved
Thanks @reinhapa I have pushed an additional commit which I think addresses the issues that you found. |
This PR fixes some cases where
xs:base64Binary
value variables within an XQuery are cleared before they should be.Diagnosis of the problem
If you have a function which returns a Map containing an
xs:base64Binary
(specifically the result of an EXPath HTTP Client response), and then you try and use that value in a calling function you will encounter an error where the temporary file backing the xs:base64Binary value has incorrectly already been deleted.What is happening is:
xs:base64Binary
value usingorg.exist.xquery.value.BinaryValueFromFile
.BinaryValueFromFile
stores the binary data in a temporary file.destroy
on the variable; this is done to clean up variables that are no longer needed.BinaryValueFromFile
to delete the temporary file.Further work in Future
Ultimately, how eXist-db determines whether a Variable is still "in-scope" or "out-of-scope" within an XQuery is far too limited and does not match the semantics of the XQuery language specifications.
The current implementation of this in eXist-db is mostly within
XQueryContext#markLocalVariables
andXQueryContext#popLocalVariables
.Fixing this completely would require substantiate changes to both eXist-db's XQuery Parser and Interpreter.
Post-script
It is not possible to write a test for this with the way that eXist-db is currently structured. A test for this should be in the Core module. However, the only way I have found to easily trigger it is via the EXPath HTTP Client which is itself in Extension Modules. To introduce a dependency between Core and Extension Modules, when there is already a dependency between Extension Modules and Core would cause a cycle in the build graph (and the build would be rejected by Maven).