Unverified Commit eb635bf0 authored by Kenton Varda's avatar Kenton Varda Committed by GitHub

Merge pull request #730 from capnproto/more-0.7-fixes

More 0.7 fixes
parents aac0274c eaefd922
......@@ -382,10 +382,14 @@ public:
kj::StringPtr dir = spec.slice(*split + 1);
auto plugin = spec.slice(0, *split);
KJ_IF_MAYBE(split2, dir.findFirst(':')) {
// Grr, there are two colons. Might this be a Windows path? Let's do some heuristics.
if (*split == 1 && (dir.startsWith("/") || dir.startsWith("\\"))) {
// So, the first ':' was the second char, and was followed by '/' or '\', e.g.:
if (*split == 1 && (dir.startsWith("/") || dir.startsWith("\\"))) {
// The colon is the second character and is immediately followed by a slash or backslash.
// So, the user passed something like `-o c:/foo`. Is this a request to run the C plugin
// and output to `/foo`? Or are we on Windows, and is this a request to run the plugin
// `c:/foo`?
KJ_IF_MAYBE(split2, dir.findFirst(':')) {
// There are two colons. The first ':' was the second char, and was followed by '/' or
// '\', e.g.:
// capnp compile -o c:/foo.exe:bar
//
// In this case we can conclude that the second colon is actually meant to be the
......@@ -407,18 +411,24 @@ public:
// -> CONTRADICTION
//
// We therefore conclude that the *second* colon is in fact the plugin/location separator.
//
// Note that there is still an ambiguous case:
// capnp compile -o c:/foo
//
// In this unfortunate case, we have no way to tell if the user meant "use the 'c' plugin
// and output to /foo" or "use the plugin c:/foo and output to the default location". We
// prefer the former interpretation, because the latter is Windows-specific and such
// users can always explicitly specify the output location like:
// capnp compile -o c:/foo:.
dir = dir.slice(*split2 + 1);
plugin = spec.slice(0, *split2 + 2);
#if _WIN32
} else {
// The user wrote something like:
//
// capnp compile -o c:/foo/bar
//
// What does this mean? It depends on what system we're on. On a Unix system, the above
// clearly is a request to run the `capnpc-c` plugin (perhaps to output C code) and write
// to the directory /foo/bar. But on Windows, absolute paths do not start with '/', and
// the above is actually a request to run the plugin `c:/foo/bar`, outputting to the
// current directory.
outputs.add(OutputDirective { spec.asArray(), nullptr });
return true;
#endif
}
}
......
......@@ -1955,6 +1955,19 @@ TEST(Encoding, ListSize) {
EXPECT_EQ(structSize.wordCount - shallowSize, listSizes.wordCount);
}
KJ_TEST("list.setWithCaveats(i, list[i]) doesn't corrupt contents") {
MallocMessageBuilder builder;
auto root = builder.initRoot<TestAllTypes>();
auto list = root.initStructList(2);
initTestMessage(list[0]);
list.setWithCaveats(0, list[0]);
checkTestMessage(list[0]);
checkTestMessageAllZero(list[1]);
list.setWithCaveats(1, list[0]);
checkTestMessage(list[0]);
checkTestMessage(list[1]);
}
} // namespace
} // namespace _ (private)
} // namespace capnp
......@@ -2853,6 +2853,17 @@ void StructBuilder::transferContentFrom(StructBuilder other) {
void StructBuilder::copyContentFrom(StructReader other) {
// Determine the amount of data the builders have in common.
auto sharedDataSize = kj::min(dataSize, other.dataSize);
auto sharedPointerCount = kj::min(pointerCount, other.pointerCount);
if ((sharedDataSize > ZERO * BITS && other.data == data) ||
(sharedPointerCount > ZERO * POINTERS && other.pointers == pointers)) {
// At least one of the section pointers is pointing to ourself. Verify that the other is two
// (but ignore empty sections).
KJ_ASSERT((sharedDataSize == ZERO * BITS || other.data == data) &&
(sharedPointerCount == ZERO * POINTERS || other.pointers == pointers));
// So `other` appears to be a reader for this same struct. No coping is needed.
return;
}
if (dataSize > sharedDataSize) {
// Since the target is larger than the source, make sure to zero out the extra bits that the
......@@ -2882,7 +2893,6 @@ void StructBuilder::copyContentFrom(StructReader other) {
WireHelpers::zeroMemory(pointers, pointerCount);
// Copy the pointers.
auto sharedPointerCount = kj::min(pointerCount, other.pointerCount);
for (auto i: kj::zeroTo(sharedPointerCount)) {
WireHelpers::copyPointer(segment, capTable, pointers + i,
other.segment, other.capTable, other.pointers + i, other.nestingLimit);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment