]> granicus.if.org Git - ejabberd/commitdiff
Unwrap carbon copies when checking for chat states
authorHolger Weiss <holger@zedat.fu-berlin.de>
Fri, 3 Jun 2016 18:28:48 +0000 (20:28 +0200)
committerHolger Weiss <holger@zedat.fu-berlin.de>
Fri, 3 Jun 2016 18:28:48 +0000 (20:28 +0200)
Detect standalone chat states that were carbon-copied.

src/jlib.erl
src/mod_client_state.erl
src/mod_offline.erl

index 8fe2b9774d64a8f1b650fe50b7b95d6c7de6c657..42ac4bff31c5015c30a6fc7661e27eacdbe83b02 100644 (file)
@@ -43,7 +43,7 @@
         get_iq_namespace/1, iq_query_info/1,
         iq_query_or_response_info/1, is_iq_request_type/1,
         iq_to_xml/1, parse_xdata_submit/1,
-        is_standalone_chat_state/1,
+        unwrap_carbon/1, is_standalone_chat_state/1,
         add_delay_info/3, add_delay_info/4,
         timestamp_to_legacy/1, timestamp_to_iso_basic/1, timestamp_to_iso/2,
         now_to_utc_string/1, now_to_local_string/1,
@@ -529,6 +529,49 @@ rsm_encode_count(Count, Arr) ->
            children = [{xmlcdata, i2l(Count)}]}
      | Arr].
 
+-spec unwrap_carbon(xmlel()) -> xmlel().
+
+unwrap_carbon(#xmlel{name = <<"message">>} = Stanza) ->
+    case unwrap_carbon(Stanza, <<"sent">>) of
+      #xmlel{} = Payload ->
+         Payload;
+      false ->
+         case unwrap_carbon(Stanza, <<"received">>) of
+           #xmlel{} = Payload ->
+               Payload;
+           false ->
+               Stanza
+         end
+    end;
+unwrap_carbon(Stanza) -> Stanza.
+
+-spec unwrap_carbon(xmlel(), binary()) -> xmlel() | false.
+
+unwrap_carbon(Stanza, Direction) ->
+    case fxml:get_subtag(Stanza, Direction) of
+      #xmlel{name = Direction, attrs = Attrs} = El ->
+         case fxml:get_attr_s(<<"xmlns">>, Attrs) of
+           NS when NS == ?NS_CARBONS_2;
+                   NS == ?NS_CARBONS_1 ->
+               case fxml:get_subtag_with_xmlns(El, <<"forwarded">>,
+                                               ?NS_FORWARD) of
+                 #xmlel{children = Els} ->
+                     case fxml:remove_cdata(Els) of
+                       [#xmlel{} = Payload] ->
+                           Payload;
+                       _ ->
+                           false
+                     end;
+                 false ->
+                     false
+               end;
+           _NS ->
+               false
+         end;
+      false ->
+         false
+    end.
+
 -spec is_standalone_chat_state(xmlel()) -> boolean().
 
 is_standalone_chat_state(#xmlel{name = <<"message">>, children = Els}) ->
index 0d3a289a3d548179197bcb75f2cfa02952bacf42..6b79aec0d93e4fae9816b28629d96da5404a8cbe 100644 (file)
@@ -165,7 +165,7 @@ filter_presence(Acc, _Host, _Stanza) -> Acc.
 
 filter_chat_states({C2SState, _OutStanzas} = Acc, Host,
                   #xmlel{name = <<"message">>} = Stanza) ->
-    case jlib:is_standalone_chat_state(Stanza) of
+    case jlib:is_standalone_chat_state(jlib:unwrap_carbon(Stanza)) of
       true ->
          ?DEBUG("Got standalone chat state notification", []),
          queue_add(chatstate, Stanza, Host, C2SState);
index 4d8aba76204f8c3548fef27347e547d092bb8d4a..74fbcd99bb33e071d4bc0c0185b24b4271fd5fa6 100644 (file)
@@ -455,7 +455,8 @@ need_to_store(LServer, Packet) ->
                                false ->
                                    fxml:get_subtag(Packet, <<"body">>) /= false;
                                unless_chat_state ->
-                                   not jlib:is_standalone_chat_state(Packet);
+                                   not jlib:is_standalone_chat_state(
+                                         jlib:unwrap_carbon(Packet));
                                true ->
                                    true
                            end