zeroc-ice 3.8.0 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/dist/IceRuby/Operation.cpp +22 -6
  3. data/dist/IceRuby/Slice.cpp +1 -1
  4. data/dist/ice/cpp/include/Ice/Communicator.h +4 -4
  5. data/dist/ice/cpp/include/Ice/Config.h +2 -2
  6. data/dist/ice/cpp/include/Ice/Connection.h +3 -3
  7. data/dist/ice/cpp/include/Ice/Endpoint.h +2 -2
  8. data/dist/ice/cpp/include/Ice/Exception.h +1 -1
  9. data/dist/ice/cpp/include/Ice/Initialize.h +1 -1
  10. data/dist/ice/cpp/include/Ice/LocalExceptions.h +22 -1
  11. data/dist/ice/cpp/include/Ice/Logger.h +3 -3
  12. data/dist/ice/cpp/include/Ice/NativePropertiesAdmin.h +2 -0
  13. data/dist/ice/cpp/include/Ice/ObjectAdapter.h +3 -3
  14. data/dist/ice/cpp/include/Ice/ObserverHelper.h +1 -0
  15. data/dist/ice/cpp/include/Ice/OutputStream.h +27 -5
  16. data/dist/ice/cpp/include/Ice/Properties.h +3 -3
  17. data/dist/ice/cpp/include/Ice/Proxy.h +1 -1
  18. data/dist/ice/cpp/include/Ice/SSL/ClientAuthenticationOptions.h +10 -2
  19. data/dist/ice/cpp/include/Ice/SSL/ServerAuthenticationOptions.h +10 -2
  20. data/dist/ice/cpp/include/generated/Ice/BuiltinSequences.h +2 -2
  21. data/dist/ice/cpp/include/generated/Ice/Context.h +2 -2
  22. data/dist/ice/cpp/include/generated/Ice/EndpointTypes.h +2 -2
  23. data/dist/ice/cpp/include/generated/Ice/Identity.h +2 -2
  24. data/dist/ice/cpp/include/generated/Ice/Locator.h +9 -11
  25. data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +2 -2
  26. data/dist/ice/cpp/include/generated/Ice/Metrics.h +7 -7
  27. data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
  28. data/dist/ice/cpp/include/generated/Ice/Process.h +2 -2
  29. data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +2 -2
  30. data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
  31. data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +2 -2
  32. data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +8 -4
  33. data/dist/ice/cpp/include/generated/Ice/Router.h +7 -7
  34. data/dist/ice/cpp/include/generated/Ice/SliceChecksumDict.h +2 -2
  35. data/dist/ice/cpp/include/generated/Ice/Version.h +2 -2
  36. data/dist/ice/cpp/include/generated/IceDiscovery/Lookup.h +2 -2
  37. data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +2 -2
  38. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +5 -3
  39. data/dist/ice/cpp/src/Ice/ConnectionFactory.h +8 -8
  40. data/dist/ice/cpp/src/Ice/ConnectionI.cpp +28 -11
  41. data/dist/ice/cpp/src/Ice/ConnectionI.h +1 -1
  42. data/dist/ice/cpp/src/Ice/Demangle.cpp +1 -0
  43. data/dist/ice/cpp/src/Ice/FileUtil.cpp +3 -67
  44. data/dist/ice/cpp/src/Ice/FileUtil.h +0 -3
  45. data/dist/ice/cpp/src/Ice/IPEndpointI.cpp +4 -0
  46. data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +1 -1
  47. data/dist/ice/cpp/src/Ice/InputStream.cpp +28 -17
  48. data/dist/ice/cpp/src/Ice/LocalException.cpp +1 -1
  49. data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +6 -0
  50. data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +1 -1
  51. data/dist/ice/cpp/src/Ice/OutgoingResponse.cpp +127 -127
  52. data/dist/ice/cpp/src/Ice/OutgoingResponseInternal.h +21 -0
  53. data/dist/ice/cpp/src/Ice/OutputStream.cpp +80 -115
  54. data/dist/ice/cpp/src/Ice/PropertyNames.cpp +3 -2
  55. data/dist/ice/cpp/src/Ice/ProxyFunctions.cpp +4 -4
  56. data/dist/ice/cpp/src/Ice/Reference.cpp +15 -15
  57. data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +16 -13
  58. data/dist/ice/cpp/src/Ice/ResourceConfig.h +2 -2
  59. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +29 -20
  60. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.h +1 -2
  61. data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp +14 -3
  62. data/dist/ice/cpp/src/Ice/SSL/RFC2253.cpp +3 -3
  63. data/dist/ice/cpp/src/Ice/SSL/SSLEndpointI.cpp +1 -1
  64. data/dist/ice/cpp/src/Ice/SSL/SSLEngine.h +4 -10
  65. data/dist/ice/cpp/src/Ice/SSL/SSLUtil.cpp +21 -2
  66. data/dist/ice/cpp/src/Ice/SSL/SSLUtil.h +15 -1
  67. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +67 -48
  68. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.h +1 -5
  69. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +14 -2
  70. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +111 -15
  71. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.h +7 -2
  72. data/dist/ice/cpp/src/Ice/SSL/SecureTransportTransceiverI.h +1 -1
  73. data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.cpp +3 -16
  74. data/dist/ice/cpp/src/Ice/SSL/TrustManager.cpp +12 -1
  75. data/dist/ice/cpp/src/Ice/ServantManager.h +1 -1
  76. data/dist/ice/cpp/src/Ice/StringConverter.cpp +4 -0
  77. data/dist/ice/cpp/src/Ice/TcpEndpointI.cpp +2 -2
  78. data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +2 -2
  79. data/dist/ice/cpp/src/Ice/WSAcceptor.cpp +8 -3
  80. data/dist/ice/cpp/src/Ice/WSAcceptor.h +5 -1
  81. data/dist/ice/cpp/src/Ice/WSEndpoint.cpp +45 -2
  82. data/dist/ice/cpp/src/Ice/WSTransceiver.cpp +118 -7
  83. data/dist/ice/cpp/src/Ice/WSTransceiver.h +12 -1
  84. data/dist/ice/cpp/src/Ice/generated/BuiltinSequences.cpp +2 -2
  85. data/dist/ice/cpp/src/Ice/generated/Context.cpp +2 -2
  86. data/dist/ice/cpp/src/Ice/generated/EndpointTypes.cpp +2 -2
  87. data/dist/ice/cpp/src/Ice/generated/Identity.cpp +2 -2
  88. data/dist/ice/cpp/src/Ice/generated/Locator.cpp +2 -2
  89. data/dist/ice/cpp/src/Ice/generated/LocatorRegistry.cpp +2 -2
  90. data/dist/ice/cpp/src/Ice/generated/Metrics.cpp +2 -2
  91. data/dist/ice/cpp/src/Ice/generated/OperationMode.cpp +2 -2
  92. data/dist/ice/cpp/src/Ice/generated/Process.cpp +2 -2
  93. data/dist/ice/cpp/src/Ice/generated/PropertiesAdmin.cpp +2 -2
  94. data/dist/ice/cpp/src/Ice/generated/PropertyDict.cpp +2 -2
  95. data/dist/ice/cpp/src/Ice/generated/RemoteLogger.cpp +2 -2
  96. data/dist/ice/cpp/src/Ice/generated/ReplyStatus.cpp +4 -2
  97. data/dist/ice/cpp/src/Ice/generated/Router.cpp +2 -2
  98. data/dist/ice/cpp/src/Ice/generated/SliceChecksumDict.cpp +2 -2
  99. data/dist/ice/cpp/src/Ice/generated/Version.cpp +2 -2
  100. data/dist/ice/cpp/src/IceDiscovery/LocatorI.cpp +2 -2
  101. data/dist/ice/cpp/src/IceDiscovery/LookupI.cpp +4 -3
  102. data/dist/ice/cpp/src/IceDiscovery/LookupI.h +2 -1
  103. data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
  104. data/dist/ice/cpp/src/IceLocatorDiscovery/PluginI.cpp +6 -18
  105. data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
  106. data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +6 -6
  107. data/dist/ice/cpp/src/Slice/DocCommentParser.h +4 -2
  108. data/dist/ice/cpp/src/Slice/FileTracker.h +1 -0
  109. data/dist/ice/cpp/src/Slice/Grammar.cpp +261 -264
  110. data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +39 -7
  111. data/dist/ice/cpp/src/Slice/MetadataValidation.h +3 -2
  112. data/dist/ice/cpp/src/Slice/Parser.cpp +192 -155
  113. data/dist/ice/cpp/src/Slice/Parser.h +44 -9
  114. data/dist/ice/cpp/src/Slice/Preprocessor.cpp +76 -20
  115. data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -1
  116. data/dist/ice/cpp/src/Slice/Scanner.cpp +1 -1
  117. data/dist/ice/cpp/src/Slice/SliceUtil.cpp +44 -58
  118. data/dist/ice/cpp/src/Slice/StringLiteralUtil.cpp +3 -10
  119. data/dist/ice/cpp/src/Slice/Util.h +7 -3
  120. data/dist/ice/cpp/src/slice2rb/Main.cpp +2 -2
  121. data/dist/ice/cpp/src/slice2rb/Ruby.cpp +1 -1
  122. data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +10 -8
  123. data/dist/ice/cpp/src/slice2rb/RubyUtil.h +10 -13
  124. data/dist/ice/mcpp/directive.c +5 -2
  125. data/dist/ice/mcpp/mcpp_main.c +1 -1
  126. data/dist/ice/mcpp/support.c +6 -6
  127. data/dist/ice/mcpp/system.c +5 -5
  128. data/dist/ice/slice/Ice/Identity.ice +3 -0
  129. data/dist/ice/slice/Ice/Locator.ice +6 -5
  130. data/dist/ice/slice/Ice/LocatorRegistry.ice +3 -0
  131. data/dist/ice/slice/Ice/Metrics.ice +1 -1
  132. data/dist/ice/slice/Ice/OperationMode.ice +8 -0
  133. data/dist/ice/slice/Ice/Process.ice +3 -0
  134. data/dist/ice/slice/Ice/ReplyStatus.ice +13 -0
  135. data/dist/lib/Glacier2/Metrics.rb +1 -1
  136. data/dist/lib/Glacier2/PermissionsVerifier.rb +3 -3
  137. data/dist/lib/Glacier2/Router.rb +8 -8
  138. data/dist/lib/Glacier2/SSLInfo.rb +1 -1
  139. data/dist/lib/Glacier2/Session.rb +15 -15
  140. data/dist/lib/Ice/BuiltinSequences.rb +1 -1
  141. data/dist/lib/Ice/Context.rb +1 -1
  142. data/dist/lib/Ice/EndpointTypes.rb +1 -1
  143. data/dist/lib/Ice/Identity.rb +1 -1
  144. data/dist/lib/Ice/LocalExceptions.rb +3 -0
  145. data/dist/lib/Ice/Locator.rb +5 -5
  146. data/dist/lib/Ice/LocatorRegistry.rb +4 -4
  147. data/dist/lib/Ice/Metrics.rb +7 -7
  148. data/dist/lib/Ice/OperationMode.rb +1 -1
  149. data/dist/lib/Ice/Process.rb +3 -3
  150. data/dist/lib/Ice/PropertiesAdmin.rb +4 -4
  151. data/dist/lib/Ice/PropertyDict.rb +1 -1
  152. data/dist/lib/Ice/ProxyFunctions.rb +8 -4
  153. data/dist/lib/Ice/RemoteLogger.rb +6 -6
  154. data/dist/lib/Ice/ReplyStatus.rb +3 -2
  155. data/dist/lib/Ice/Router.rb +5 -5
  156. data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
  157. data/dist/lib/Ice/Version.rb +1 -1
  158. data/dist/lib/IceBox/ServiceManager.rb +8 -8
  159. data/dist/lib/IceGrid/Admin.rb +83 -83
  160. data/dist/lib/IceGrid/Descriptor.rb +1 -1
  161. data/dist/lib/IceGrid/Exception.rb +1 -1
  162. data/dist/lib/IceGrid/FileParser.rb +2 -2
  163. data/dist/lib/IceGrid/Registry.rb +13 -13
  164. data/dist/lib/IceGrid/Session.rb +6 -6
  165. data/dist/lib/IceGrid/UserAccountMapper.rb +2 -2
  166. data/dist/lib/IceStorm/IceStorm.rb +16 -16
  167. data/dist/lib/IceStorm/Metrics.rb +1 -1
  168. data/ice.gemspec +1 -1
  169. metadata +2 -1
@@ -33,7 +33,7 @@ IncomingRequest::IncomingRequest(
33
33
  {
34
34
  throw MarshalException{__FILE__, __LINE__, "received facet path with more than one element"};
35
35
  }
36
- _current.facet = facetPath[0];
36
+ _current.facet = std::move(facetPath[0]);
37
37
  }
38
38
 
39
39
  inputStream.read(_current.operation, false);
@@ -143,8 +143,6 @@ Ice::InputStream::operator=(InputStream&& other) noexcept
143
143
  _closure = other._closure;
144
144
  _startSeq = other._startSeq;
145
145
  _minSeqSize = other._minSeqSize;
146
- _startSeq = -1;
147
- _minSeqSize = 0;
148
146
  resetEncapsulation();
149
147
 
150
148
  // Reset other to its default state.
@@ -430,14 +428,19 @@ Ice::InputStream::readAndCheckSeqSize(int minSize)
430
428
  // the estimated remaining buffer size. This estimation is based on
431
429
  // the minimum size of the enclosing sequences, it's _minSeqSize.
432
430
  //
433
- if (_startSeq == -1 || i > (b.begin() + _startSeq + _minSeqSize))
431
+ // 'sz' is peer-controlled (up to INT32_MAX), so we compute the minimum size of this sequence in
432
+ // 64-bit: 'sz * minSize' would otherwise overflow a 32-bit int and bypass the bounds check below.
433
+ int64_t minSeqSize = static_cast<int64_t>(sz) * minSize;
434
+
435
+ // '_startSeq + _minSeqSize' does not overflow: on the previous call, the bounds check below
436
+ // established this sum is <= b.size(), itself smaller than INT32_MAX.
437
+ if (_startSeq == -1 || (i - b.begin()) > _startSeq + _minSeqSize)
434
438
  {
435
439
  _startSeq = static_cast<int>(i - b.begin());
436
- _minSeqSize = sz * minSize;
437
440
  }
438
441
  else
439
442
  {
440
- _minSeqSize += sz * minSize;
443
+ minSeqSize += _minSeqSize;
441
444
  }
442
445
 
443
446
  //
@@ -445,11 +448,13 @@ Ice::InputStream::readAndCheckSeqSize(int minSize)
445
448
  // possibly enclosed sequences), something is wrong with the marshaled
446
449
  // data: it's claiming having more data that what is possible to read.
447
450
  //
448
- if (_startSeq + _minSeqSize > static_cast<int>(b.size()))
451
+ if (_startSeq + minSeqSize > static_cast<int64_t>(b.size()))
449
452
  {
450
453
  throwUnmarshalOutOfBoundsException(__FILE__, __LINE__);
451
454
  }
452
455
 
456
+ // minSeqSize is now known to be <= b.size(), itself smaller than INT32_MAX.
457
+ _minSeqSize = static_cast<int>(minSeqSize);
453
458
  return sz;
454
459
  }
455
460
 
@@ -476,15 +481,7 @@ Ice::InputStream::read(std::vector<byte>& v)
476
481
  {
477
482
  std::pair<const byte*, const byte*> p;
478
483
  read(p);
479
- if (p.first != p.second)
480
- {
481
- v.resize(static_cast<size_t>(p.second - p.first));
482
- copy(p.first, p.second, v.begin());
483
- }
484
- else
485
- {
486
- v.clear();
487
- }
484
+ v.assign(p.first, p.second);
488
485
  }
489
486
 
490
487
  void
@@ -1144,6 +1141,13 @@ Ice::InputStream::readOptImpl(int32_t readTag, OptionalFormat expectedFormat)
1144
1141
 
1145
1142
  auto format = static_cast<OptionalFormat>(v & 0x07); // First 3 bits.
1146
1143
  auto tag = static_cast<int32_t>(v >> 3);
1144
+ if (tag > 30)
1145
+ {
1146
+ // We check for '> 30' instead of '> 29' because 30 is special sentinel tag, handled by the next block.
1147
+ ostringstream os;
1148
+ os << "invalid tag '" << tag << "': tags larger than 29 must be encoded as a size";
1149
+ throw MarshalException(__FILE__, __LINE__, os.str());
1150
+ }
1147
1151
  if (tag == 30)
1148
1152
  {
1149
1153
  tag = readSize();
@@ -1918,7 +1922,11 @@ Ice::InputStream::EncapsDecoder11::startSlice()
1918
1922
  if (_current->sliceFlags & FLAG_HAS_SLICE_SIZE)
1919
1923
  {
1920
1924
  _stream->read(_current->sliceSize);
1921
- if (_current->sliceSize < 4)
1925
+ // A slice with optional members carries at least the 1-byte end marker in its body, so its
1926
+ // size (which includes the 4-byte size field) must be >= 5. We rely on this in skipSlice's
1927
+ // slice-preservation logic, which excludes the end marker by stepping back one byte.
1928
+ int32_t minSliceSize = (_current->sliceFlags & FLAG_HAS_OPTIONAL_MEMBERS) ? 5 : 4;
1929
+ if (_current->sliceSize < minSliceSize)
1922
1930
  {
1923
1931
  throw MarshalException{__FILE__, __LINE__, endOfBufferMessage};
1924
1932
  }
@@ -2076,7 +2084,10 @@ Ice::InputStream::EncapsDecoder11::readOptional(int32_t readTag, Ice::OptionalFo
2076
2084
  int32_t
2077
2085
  Ice::InputStream::EncapsDecoder11::readInstance(int32_t index, const PatchFunc& patchFunc, void* patchAddr)
2078
2086
  {
2079
- assert(index > 0);
2087
+ if (index <= 0)
2088
+ {
2089
+ throw MarshalException(__FILE__, __LINE__, "invalid class instance index");
2090
+ }
2080
2091
 
2081
2092
  if (index > 1)
2082
2093
  {
@@ -48,7 +48,7 @@
48
48
  # endif
49
49
  # endif
50
50
 
51
- # if !defined(__FreeBSD__)
51
+ # if __has_include(<execinfo.h>)
52
52
  # include <cstdint>
53
53
  # include <execinfo.h>
54
54
  # define ICE_BACKTRACE
@@ -570,6 +570,12 @@ Ice::TwowayOnlyException::ice_id() const noexcept
570
570
  return "::Ice::TwowayOnlyException";
571
571
  }
572
572
 
573
+ const char*
574
+ Ice::OnewayOnlyException::ice_id() const noexcept
575
+ {
576
+ return "::Ice::OnewayOnlyException";
577
+ }
578
+
573
579
  const char*
574
580
  Ice::PropertyException::ice_id() const noexcept
575
581
  {
@@ -817,7 +817,7 @@ OutgoingAsync::prepare(string_view operation, OperationMode mode, const Context&
817
817
  }
818
818
  else
819
819
  {
820
- string facet = ref->getFacet();
820
+ const string& facet = ref->getFacet();
821
821
  _os.write(&facet, &facet + 1);
822
822
  }
823
823
 
@@ -2,9 +2,11 @@
2
2
 
3
3
  #include "Ice/OutgoingResponse.h"
4
4
  #include "Ice/Demangle.h"
5
+ #include "Ice/Initialize.h"
5
6
  #include "Ice/LocalExceptions.h"
6
7
  #include "Ice/ObjectAdapter.h"
7
8
  #include "Ice/UserException.h"
9
+ #include "OutgoingResponseInternal.h"
8
10
  #include "Protocol.h"
9
11
 
10
12
  #include <sstream>
@@ -30,131 +32,6 @@ namespace
30
32
  os << "dispatch failed with " << typeId << ": " << what;
31
33
  return os.str();
32
34
  }
33
-
34
- // The "core" implementation of makeOutgoingResponse for exceptions. Note that it can throw an exception.
35
- OutgoingResponse makeOutgoingResponseCore(std::exception_ptr exc, const Current& current)
36
- {
37
- assert(exc);
38
- OutputStream ostr{currentProtocolEncoding};
39
-
40
- if (current.requestId != 0)
41
- {
42
- ostr.writeBlob(replyHdr, sizeof(replyHdr));
43
- ostr.write(current.requestId);
44
- }
45
- ReplyStatus replyStatus;
46
- string exceptionId;
47
- string exceptionDetails; // may include the stack trace.
48
- string dispatchExceptionMessage;
49
-
50
- try
51
- {
52
- rethrow_exception(exc);
53
- }
54
- catch (const UserException& ex)
55
- {
56
- // We keep exceptionId and exceptionDetails empty.
57
-
58
- replyStatus = ReplyStatus::UserException;
59
-
60
- if (current.requestId != 0)
61
- {
62
- ostr.write(replyStatus);
63
- ostr.startEncapsulation(current.encoding, FormatType::SlicedFormat);
64
- ostr.write(ex);
65
- ostr.endEncapsulation();
66
- }
67
- }
68
- catch (const DispatchException& ex)
69
- {
70
- exceptionId = ex.ice_id();
71
- exceptionDetails = toString(ex); // can include a stack trace
72
- replyStatus = ex.replyStatus();
73
-
74
- if (replyStatus >= ReplyStatus::ObjectNotExist && replyStatus <= ReplyStatus::OperationNotExist)
75
- {
76
- if (current.requestId != 0) // only marshal response for two-way requests
77
- {
78
- // The identity, facet, operation are often left unset at this point.
79
- Identity id;
80
- string facet;
81
- string operation;
82
- if (auto* rfe = dynamic_cast<const RequestFailedException*>(&ex))
83
- {
84
- id = rfe->id();
85
- facet = rfe->facet();
86
- operation = rfe->operation();
87
- }
88
- if (id.name.empty())
89
- {
90
- id = current.id;
91
- facet = current.facet;
92
- }
93
- if (operation.empty())
94
- {
95
- operation = current.operation;
96
- }
97
-
98
- ostr.write(replyStatus);
99
- ostr.write(id);
100
-
101
- if (facet.empty())
102
- {
103
- ostr.write(static_cast<string*>(nullptr), static_cast<string*>(nullptr));
104
- }
105
- else
106
- {
107
- ostr.write(&facet, &facet + 1);
108
- }
109
- ostr.write(operation, false);
110
- }
111
- // dispatchExceptionMessage remains empty: RequestFailedException does not carry a message and we
112
- // don't include this message in OutgoingResponse.
113
- }
114
- else
115
- {
116
- dispatchExceptionMessage = ex.what();
117
- // And marshal this exception after the last catch block.
118
- }
119
- }
120
- catch (const LocalException& ex)
121
- {
122
- exceptionId = ex.ice_id();
123
- exceptionDetails = toString(ex);
124
- dispatchExceptionMessage = createDispatchExceptionMessage(exceptionId, ex.what());
125
- replyStatus = ReplyStatus::UnknownLocalException;
126
- }
127
- catch (const std::exception& ex)
128
- {
129
- exceptionId = demangle(typeid(ex).name());
130
- ostringstream str;
131
- str << "c++ exception: " << ex.what();
132
- exceptionDetails = str.str();
133
- dispatchExceptionMessage = createDispatchExceptionMessage(exceptionId, ex.what());
134
- replyStatus = ReplyStatus::UnknownException;
135
- }
136
- catch (...)
137
- {
138
- exceptionId = "unknown";
139
- exceptionDetails = "c++ exception: unknown";
140
- dispatchExceptionMessage = createDispatchExceptionMessage(exceptionId, "c++ exception");
141
- replyStatus = ReplyStatus::UnknownException;
142
- }
143
-
144
- if (current.requestId != 0 && replyStatus > ReplyStatus::OperationNotExist)
145
- {
146
- // We can't use the generated code to marshal a possibly unknown reply status.
147
- ostr.write(static_cast<uint8_t>(replyStatus));
148
- ostr.write(dispatchExceptionMessage);
149
- }
150
-
151
- return OutgoingResponse{
152
- replyStatus,
153
- std::move(exceptionId),
154
- std::move(exceptionDetails),
155
- std::move(ostr),
156
- current};
157
- }
158
35
  } // anonymous namespace
159
36
 
160
37
  OutgoingResponse::OutgoingResponse(
@@ -264,13 +141,136 @@ Ice::makeOutgoingResponse(bool ok, pair<const byte*, const byte*> encapsulation,
264
141
  OutgoingResponse
265
142
  Ice::makeOutgoingResponse(std::exception_ptr exc, const Current& current) noexcept
266
143
  {
144
+ IceInternal::Instance* instance = getInstance(current.adapter->getCommunicator()).get();
145
+
267
146
  try
268
147
  {
269
- return makeOutgoingResponseCore(exc, current);
148
+ return makeOutgoingResponseCore(exc, current, instance);
270
149
  }
271
150
  catch (...)
272
151
  {
273
152
  // This could throw again, but then it's either a bug or we can't allocate anything.
274
- return makeOutgoingResponseCore(current_exception(), current);
153
+ return makeOutgoingResponseCore(current_exception(), current, instance);
275
154
  }
276
155
  }
156
+
157
+ // The "core" implementation of makeOutgoingResponse for exceptions. Note that it can throw an exception.
158
+ OutgoingResponse
159
+ Ice::makeOutgoingResponseCore(std::exception_ptr exc, const Current& current, Instance* instance)
160
+ {
161
+ assert(exc);
162
+ OutputStream ostr{instance, currentProtocolEncoding};
163
+
164
+ if (current.requestId != 0)
165
+ {
166
+ ostr.writeBlob(replyHdr, sizeof(replyHdr));
167
+ ostr.write(current.requestId);
168
+ }
169
+ ReplyStatus replyStatus;
170
+ string exceptionId;
171
+ string exceptionDetails; // may include the stack trace.
172
+ string dispatchExceptionMessage;
173
+
174
+ try
175
+ {
176
+ rethrow_exception(exc);
177
+ }
178
+ catch (const UserException& ex)
179
+ {
180
+ // We keep exceptionId and exceptionDetails empty.
181
+
182
+ replyStatus = ReplyStatus::UserException;
183
+
184
+ if (current.requestId != 0)
185
+ {
186
+ ostr.write(replyStatus);
187
+ ostr.startEncapsulation(current.encoding, FormatType::SlicedFormat);
188
+ ostr.write(ex);
189
+ ostr.endEncapsulation();
190
+ }
191
+ }
192
+ catch (const DispatchException& ex)
193
+ {
194
+ exceptionId = ex.ice_id();
195
+ exceptionDetails = toString(ex); // can include a stack trace
196
+ replyStatus = ex.replyStatus();
197
+
198
+ if (replyStatus >= ReplyStatus::ObjectNotExist && replyStatus <= ReplyStatus::OperationNotExist)
199
+ {
200
+ if (current.requestId != 0) // only marshal response for two-way requests
201
+ {
202
+ // The identity, facet, operation are often left unset at this point.
203
+ Identity id;
204
+ string facet;
205
+ string operation;
206
+ if (auto* rfe = dynamic_cast<const RequestFailedException*>(&ex))
207
+ {
208
+ id = rfe->id();
209
+ facet = rfe->facet();
210
+ operation = rfe->operation();
211
+ }
212
+ if (id.name.empty())
213
+ {
214
+ id = current.id;
215
+ facet = current.facet;
216
+ }
217
+ if (operation.empty())
218
+ {
219
+ operation = current.operation;
220
+ }
221
+
222
+ ostr.write(replyStatus);
223
+ ostr.write(id);
224
+
225
+ if (facet.empty())
226
+ {
227
+ ostr.write(static_cast<string*>(nullptr), static_cast<string*>(nullptr));
228
+ }
229
+ else
230
+ {
231
+ ostr.write(&facet, &facet + 1);
232
+ }
233
+ ostr.write(operation, false);
234
+ }
235
+ // dispatchExceptionMessage remains empty: RequestFailedException does not carry a message and we
236
+ // don't include this message in OutgoingResponse.
237
+ }
238
+ else
239
+ {
240
+ dispatchExceptionMessage = ex.what();
241
+ // And marshal this exception after the last catch block.
242
+ }
243
+ }
244
+ catch (const LocalException& ex)
245
+ {
246
+ exceptionId = ex.ice_id();
247
+ exceptionDetails = toString(ex);
248
+ dispatchExceptionMessage = createDispatchExceptionMessage(exceptionId, ex.what());
249
+ replyStatus = ReplyStatus::UnknownLocalException;
250
+ }
251
+ catch (const std::exception& ex)
252
+ {
253
+ exceptionId = demangle(typeid(ex).name());
254
+ ostringstream str;
255
+ str << "c++ exception: " << ex.what();
256
+ exceptionDetails = str.str();
257
+ dispatchExceptionMessage = createDispatchExceptionMessage(exceptionId, ex.what());
258
+ replyStatus = ReplyStatus::UnknownException;
259
+ }
260
+ catch (...)
261
+ {
262
+ exceptionId = "unknown";
263
+ exceptionDetails = "c++ exception: unknown";
264
+ dispatchExceptionMessage = createDispatchExceptionMessage(exceptionId, "c++ exception");
265
+ replyStatus = ReplyStatus::UnknownException;
266
+ }
267
+
268
+ if (current.requestId != 0 && replyStatus > ReplyStatus::OperationNotExist)
269
+ {
270
+ // We can't use the generated code to marshal a possibly unknown reply status.
271
+ ostr.write(static_cast<uint8_t>(replyStatus));
272
+ ostr.write(dispatchExceptionMessage);
273
+ }
274
+
275
+ return OutgoingResponse{replyStatus, std::move(exceptionId), std::move(exceptionDetails), std::move(ostr), current};
276
+ }
@@ -0,0 +1,21 @@
1
+ // Copyright (c) ZeroC, Inc.
2
+
3
+ #ifndef ICE_OUTGOING_RESPONSE_INTERNAL_H
4
+ #define ICE_OUTGOING_RESPONSE_INTERNAL_H
5
+
6
+ #include "Ice/OutgoingResponse.h"
7
+
8
+ namespace Ice
9
+ {
10
+ /// @private
11
+ /// The "core" implementation of makeOutgoingResponse for exceptions. Note that it can throw an exception.
12
+ /// @param exception The exception to marshal into the response.
13
+ /// @param current A reference to the Current object of the request. @c current.adapter can be null here; the
14
+ /// implementation uses @p instance instead.
15
+ /// @param instance The IceInternal::Instance object. Not null.
16
+ /// @return The new response.
17
+ OutgoingResponse
18
+ makeOutgoingResponseCore(std::exception_ptr exception, const Current& current, IceInternal::Instance* instance);
19
+ }
20
+
21
+ #endif