LCOV - code coverage report
Current view: top level - xmpp - xmpp_proto.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 236 299 78.9 %
Date: 2026-06-11 01:56:02 Functions: 22 28 78.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "xmpp/xmpp_proto.h"
       6             : #include <iostream>
       7             : #include <string>
       8             : #include <boost/algorithm/string/replace.hpp>
       9             : #include <boost/algorithm/string/predicate.hpp>
      10             : 
      11             : #include "xmpp/xmpp_connection.h"
      12             : #include "xmpp/xmpp_log.h"
      13             : #include "xmpp/xmpp_session.h"
      14             : #include "xmpp/xmpp_str.h"
      15             : 
      16             : #include "sandesh/sandesh_trace.h"
      17             : #include "sandesh/common/vns_types.h"
      18             : #include "sandesh/common/vns_constants.h"
      19             : #include "sandesh/xmpp_message_sandesh_types.h"
      20             : #include "sandesh/xmpp_trace_sandesh_types.h"
      21             : 
      22             : using namespace std;
      23             : 
      24             : unique_ptr<XmlBase> XmppProto::open_doc_(AllocXmppXmlImpl(sXMPP_STREAM_OPEN));
      25             : 
      26           0 : XmppStanza::XmppStanza() {
      27           0 : }
      28             : 
      29           0 : XmppProto::XmppProto() {
      30           0 : }
      31             : 
      32           0 : XmppProto::~XmppProto() {
      33           0 : }
      34             : 
      35       20318 : int XmppProto::EncodeStream(const XmppStreamMessage &str, string &to,
      36             :                             string &from, const string &xmlns, uint8_t *buf,
      37             :                             size_t size) {
      38       20318 :     int len = 0;
      39             : 
      40       20318 :     switch (str.strmtype) {
      41        8054 :         case (XmppStanza::XmppStreamMessage::INIT_STREAM_HEADER):
      42        8054 :             len = EncodeOpen(buf, to, from, xmlns, size);
      43        8054 :             break;
      44        7822 :         case (XmppStanza::XmppStreamMessage::INIT_STREAM_HEADER_RESP):
      45        7822 :             len = EncodeOpenResp(buf, to, from, size);
      46        7824 :             break;
      47        4444 :         case (XmppStanza::XmppStreamMessage::FEATURE_TLS):
      48        4444 :             switch (str.strmtlstype) {
      49        1512 :                 case (XmppStanza::XmppStreamMessage::TLS_FEATURE_REQUEST):
      50        1512 :                     len = EncodeFeatureTlsRequest(buf);
      51        1512 :                     break;
      52        1469 :                 case (XmppStanza::XmppStreamMessage::TLS_START):
      53        1469 :                     len = EncodeFeatureTlsStart(buf);
      54        1469 :                     break;
      55        1463 :                 case (XmppStanza::XmppStreamMessage::TLS_PROCEED):
      56        1463 :                     len = EncodeFeatureTlsProceed(buf);
      57        1464 :                     break;
      58             :             }
      59        4445 :             break;
      60           0 :         default:
      61           0 :             break;
      62             :     }
      63             : 
      64       20321 :     return len;
      65             : }
      66             : 
      67        6446 : int XmppProto::EncodeStream(const XmppStanza::XmppMessage &str, uint8_t *buf,
      68             :                             size_t size) {
      69        6446 :     int ret = 0;
      70             : 
      71        6446 :     if (str.type == XmppStanza::WHITESPACE_MESSAGE_STANZA) {
      72        6446 :         return EncodeWhitespace(buf);
      73             :     }
      74             : 
      75           0 :     return ret;
      76             : }
      77             : 
      78           0 : int XmppProto::EncodeMessage(XmlBase *dom, uint8_t *buf, size_t size) {
      79           0 :     int len = dom->WriteDoc(buf);
      80             : 
      81           0 :     return len;
      82             : }
      83             : 
      84           0 : int XmppProto::EncodePresence(uint8_t *buf, size_t size) {
      85           0 :     return 0;
      86             : }
      87             : 
      88           0 : int XmppProto::EncodeIq(const XmppStanza::XmppMessageIq *iq,
      89             :                         XmlBase *doc, uint8_t *buf, size_t size) {
      90           0 :     unique_ptr<XmlBase> send_doc_(AllocXmppXmlImpl());
      91             : 
      92             :     // create
      93           0 :     send_doc_->LoadDoc("");
      94           0 :     send_doc_->AddNode("iq", "");
      95             : 
      96           0 :     switch(iq->stype) {
      97           0 :         case XmppStanza::XmppMessageIq::GET:
      98           0 :             send_doc_->AddAttribute("type", "get");
      99           0 :             break;
     100           0 :         case XmppStanza::XmppMessageIq::SET:
     101           0 :             send_doc_->AddAttribute("type", "set");
     102           0 :             break;
     103           0 :         case XmppStanza::XmppMessageIq::RESULT:
     104           0 :             send_doc_->AddAttribute("type", "result");
     105           0 :             break;
     106           0 :         case XmppStanza::XmppMessageIq::ERROR:
     107           0 :             send_doc_->AddAttribute("type", "error");
     108           0 :             break;
     109           0 :         default:
     110           0 :             break;
     111             :     }
     112           0 :     send_doc_->AddAttribute("from", iq->from);
     113           0 :     send_doc_->AddAttribute("to", iq->to);
     114           0 :     send_doc_->AddAttribute("id", "id1");
     115             : 
     116           0 :     send_doc_->AddChildNode("pubsub", "");
     117           0 :     send_doc_->AddAttribute("xmlns", "http://jabber.org/protocol/pubsub");
     118             : 
     119           0 :     send_doc_->AppendDoc("pubsub", doc);
     120             : 
     121             :     //Returns byte encoded in the doc
     122           0 :     int len = send_doc_->WriteDoc(buf);
     123             : 
     124           0 :     return len;
     125           0 : }
     126             : 
     127        6446 : int XmppProto::EncodeWhitespace(uint8_t *buf) {
     128        6446 :     string str(sXMPP_WHITESPACE);
     129             : 
     130        6446 :     int len = str.size();
     131        6446 :     if (len > 0) {
     132        6446 :         memcpy(buf, str.data(), len);
     133             :     }
     134             : 
     135        6446 :     return len;
     136        6446 : }
     137             : 
     138        7822 : int XmppProto::EncodeOpenResp(uint8_t *buf, string &to, string &from,
     139             :                               size_t max_size) {
     140             : 
     141        7822 :     unique_ptr<XmlBase> resp_doc(XmppStanza::AllocXmppXmlImpl(sXMPP_STREAM_RESP));
     142             : 
     143        7822 :     if (resp_doc.get() == NULL) {
     144           0 :         return 0;
     145             :     }
     146             : 
     147        7822 :     SetTo(to, resp_doc.get());
     148        7823 :     SetFrom(from, resp_doc.get());
     149             : 
     150        7821 :     std::stringstream ss;
     151        7823 :     resp_doc->PrintDoc(ss);
     152        7824 :     std::string msg;
     153        7824 :     msg = ss.str();
     154        7824 :     size_t len = msg.size();
     155        7824 :     if (len > max_size) {
     156           0 :         LOG(ERROR, "\n (Open Confirm) size greater than max buffer size \n");
     157           0 :         return 0;
     158             :     } else {
     159        7824 :         boost::algorithm::ireplace_last(msg, "/", " ");
     160        7824 :         memcpy(buf, msg.c_str(), len);
     161        7824 :         return len;
     162             :     }
     163        7824 : }
     164             : 
     165        8054 : int XmppProto::EncodeOpen(uint8_t *buf, string &to, string &from,
     166             :                           const string &xmlns, size_t max_size) {
     167             : 
     168        8054 :     if (open_doc_.get() ==  NULL) {
     169           0 :         return 0;
     170             :     }
     171             : 
     172        8054 :     SetTo(to, open_doc_.get());
     173        8054 :     SetFrom(from, open_doc_.get());
     174        8054 :     SetXmlns(xmlns, open_doc_.get());
     175             : 
     176             :     //Returns byte encoded in the doc
     177        8054 :     std::stringstream ss;
     178        8054 :     open_doc_->PrintDoc(ss);
     179        8054 :     std::string msg;
     180        8054 :     msg = ss.str();
     181        8054 :     size_t len = msg.size();
     182        8054 :     if (len > max_size) {
     183           0 :         LOG(ERROR, "\n (Open Message) size greater than max buffer size \n");
     184           0 :         return 0;
     185             :     } else {
     186        8054 :         boost::algorithm::ireplace_last(msg, "/", " ");
     187        8054 :         memcpy(buf, msg.c_str(), len);
     188        8054 :         return len;
     189             :     }
     190        8054 : }
     191             : 
     192        1512 : int XmppProto::EncodeFeatureTlsRequest(uint8_t *buf) {
     193        1512 :     unique_ptr<XmlBase> resp_doc(XmppStanza::AllocXmppXmlImpl(sXMPP_STREAM_FEATURE_TLS));
     194             :     //Returns byte encoded in the doc
     195        1512 :     int len = resp_doc->WriteDoc(buf);
     196        1512 :     return len;
     197        1512 : }
     198             : 
     199        1469 : int XmppProto::EncodeFeatureTlsStart(uint8_t *buf) {
     200        1469 :     unique_ptr<XmlBase> resp_doc(XmppStanza::AllocXmppXmlImpl(sXMPP_STREAM_START_TLS));
     201             :     //Returns byte encoded in the doc
     202        1469 :     int len = resp_doc->WriteDoc(buf);
     203        1469 :     return len;
     204        1469 : }
     205             : 
     206        1463 : int XmppProto::EncodeFeatureTlsProceed(uint8_t *buf) {
     207        1463 :     unique_ptr<XmlBase> resp_doc(XmppStanza::AllocXmppXmlImpl(sXMPP_STREAM_PROCEED_TLS));
     208             :     //Returns byte encoded in the doc
     209        1464 :     int len = resp_doc->WriteDoc(buf);
     210        1464 :     return len;
     211        1463 : }
     212             : 
     213     4208575 : XmppStanza::XmppMessage *XmppProto::Decode(const XmppConnection *connection,
     214             :                                            const string &ts) {
     215     4208575 :     XmlBase *impl = XmppStanza::AllocXmppXmlImpl();
     216     4208540 :     if (impl == nullptr) {
     217           0 :         return nullptr;
     218             :     }
     219             : 
     220     4208540 :     XmppStanza::XmppMessage *msg = DecodeInternal(connection, ts, impl);
     221     4208604 :     if (!msg) {
     222           0 :         return nullptr;
     223             :     }
     224             : 
     225             :     // transfer ownership of the dom implementation
     226     4208604 :     msg->dom.reset(impl);
     227             : 
     228     4208572 :     return msg;
     229             : }
     230             : 
     231     4208537 : XmppStanza::XmppMessage *XmppProto::DecodeInternal(
     232             :         const XmppConnection *connection, const string &ts, XmlBase *impl) {
     233     4208537 :     XmppStanza::XmppMessage *ret = nullptr;
     234             : 
     235     4208537 :     string ns(sXMPP_STREAM_O);
     236     4208518 :     string ws(sXMPP_WHITESPACE);
     237     4208507 :     string iq(sXMPP_IQ_KEY);
     238             : 
     239     4208496 :     if (ts.find(sXMPP_IQ) != string::npos) {
     240       98542 :         string ts_tmp = ts;
     241             : 
     242       98542 :         if (impl->LoadDoc(ts) == -1) {
     243           0 :             XMPP_WARNING(XmppIqMessageParseFail, connection->ToUVEKey(),
     244             :                          XMPP_PEER_DIR_IN);
     245           0 :             assert(false);
     246             :             goto done;
     247             :         }
     248             : 
     249       98548 :         XmppStanza::XmppMessageIq *msg = new XmppStanza::XmppMessageIq;
     250       98545 :         impl->ReadNode(iq);
     251       98547 :         msg->to = XmppProto::GetTo(impl);
     252       98543 :         msg->from = XmppProto::GetFrom(impl);
     253       98544 :         msg->id = XmppProto::GetId(impl);
     254       98548 :         msg->iq_type = XmppProto::GetType(impl);
     255             :         // action is subscribe,publish,collection
     256       98547 :         const char *action = XmppProto::GetAction(impl, msg->iq_type);
     257       98543 :         if (action) {
     258       98527 :             msg->action = action;
     259             :         }
     260       98543 :         if (XmppProto::GetNode(impl, msg->action)) {
     261       98527 :             msg->node = XmppProto::GetNode(impl, msg->action);
     262             :         }
     263             :         //associate or dissociate collection node
     264       98543 :         if (msg->action.compare("collection") == 0) {
     265       41658 :             if (XmppProto::GetAsNode(impl)) {
     266       27301 :                 msg->as_node = XmppProto::GetAsNode(impl);
     267       27301 :                 msg->is_as_node = true;
     268       14357 :             } else if (XmppProto::GetDsNode(impl)) {
     269       14329 :                 msg->as_node = XmppProto::GetDsNode(impl);
     270       14329 :                 msg->is_as_node = false;
     271             :             }
     272             :         }
     273             : 
     274             :         //msg->dom.reset(impl);
     275             : 
     276       98544 :         ret = msg;
     277             : 
     278       98544 :         XMPP_UTDEBUG(XmppIqMessageProcess, connection->ToUVEKey(),
     279             :                      XMPP_PEER_DIR_IN, msg->node, msg->action, msg->from,
     280             :                      msg->to, msg->id, msg->iq_type);
     281       98548 :         goto done;
     282             : 
     283     4208606 :     } else if (ts.find(sXMPP_MESSAGE) != string::npos) {
     284             : 
     285     1573118 :         if (impl->LoadDoc(ts) == -1) {
     286           0 :             XMPP_WARNING(XmppChatMessageParseFail, connection->ToUVEKey(),
     287             :                          XMPP_PEER_DIR_IN);
     288           0 :             goto done;
     289             :         }
     290             :         XmppStanza::XmppMessage *msg = new XmppStanza::XmppChatMessage(
     291     1573118 :                                            STATE_NONE);
     292     1573118 :         impl->ReadNode(sXMPP_MESSAGE_KEY);
     293             : 
     294     1573118 :         msg->to = XmppProto::GetTo(impl);
     295     1573118 :         msg->from = XmppProto::GetFrom(impl);
     296     1573118 :         ret = msg;
     297             : 
     298     1573118 :         XMPP_UTDEBUG(XmppChatMessageProcess, connection->ToUVEKey(),
     299             :                      XMPP_PEER_DIR_IN, msg->type, msg->from, msg->to);
     300     1573118 :         goto done;
     301             : 
     302     2536943 :     } else if (ts.find(sXMPP_STREAM_O) != string::npos) {
     303             : 
     304             :         // ensusre stream open is at the beginning of the message
     305       15723 :         string ts_tmp = ts;
     306       15720 :         ts_tmp.erase(std::remove(ts_tmp.begin(), ts_tmp.end(), '\n'), ts_tmp.end());
     307             : 
     308       15717 :         if ((ts_tmp.compare(0, strlen(sXMPP_STREAM_START),
     309       31434 :              sXMPP_STREAM_START) != 0) &&
     310       15717 :             (ts_tmp.compare(0, strlen(sXMPP_STREAM_START_S),
     311             :              sXMPP_STREAM_START_S) != 0)) {
     312           0 :             XMPP_WARNING(XmppBadMessage, connection->ToUVEKey(),
     313             :                          XMPP_PEER_DIR_IN,
     314             :                          "Open message not at the beginning.", ts);
     315           0 :             goto done;
     316             :         }
     317             : 
     318             :         // check if the buf is xmpp open or response message
     319             :         // As end tag will be missing we need to modify the
     320             :         // string for stream open, else dom decoder will fail
     321       15717 :         boost::algorithm::replace_last(ts_tmp, ">", "/>");
     322       15717 :         if (impl->LoadDoc(ts_tmp) == -1) {
     323           0 :             XMPP_WARNING(XmppBadMessage, connection->ToUVEKey(),
     324             :                          XMPP_PEER_DIR_IN, "Open message parse failed.", ts);
     325           0 :             goto done;
     326             :         }
     327             : 
     328             :         XmppStanza::XmppStreamMessage *strm =
     329       15722 :             new XmppStanza::XmppStreamMessage();
     330       15719 :         strm->strmtype = XmppStanza::XmppStreamMessage::INIT_STREAM_HEADER;
     331       15719 :         impl->ReadNode(ns);
     332       15713 :         strm->to = XmppProto::GetTo(impl);
     333       15717 :         strm->from = XmppProto::GetFrom(impl);
     334       15719 :         strm->xmlns = XmppProto::GetXmlns(impl);
     335             : 
     336       15718 :         ret = strm;
     337             : 
     338       15718 :         XMPP_UTDEBUG(XmppRxOpenMessage, connection->ToUVEKey(),
     339             :                      XMPP_PEER_DIR_IN, strm->from, strm->to);
     340             : 
     341     2536942 :     } else if (ts.find(sXMPP_STREAM_NS_TLS) != string::npos) {
     342             : 
     343        4363 :         if (impl->LoadDoc(ts) == -1) {
     344           0 :             XMPP_WARNING(XmppBadMessage, connection->ToUVEKey(),
     345             :                          XMPP_PEER_DIR_IN, "Stream TLS parse failed.", ts);
     346           0 :             goto done;
     347             :         }
     348             : 
     349             :         // find stream:features tls required
     350        5820 :         if ((ts.find(sXMPP_STREAM_FEATURES_O) != string::npos) &&
     351        5820 :             (ts.find(sXMPP_STREAM_STARTTLS_O) != string::npos) &&
     352        1455 :             (ts.find(sXMPP_REQUIRED_O) != string::npos)) {
     353             : 
     354             :             XmppStanza::XmppStreamMessage *strm =
     355        1455 :                 new XmppStanza::XmppStreamMessage();
     356        1455 :             strm->strmtype = XmppStanza::XmppStreamMessage::FEATURE_TLS;
     357        1455 :             strm->strmtlstype = XmppStanza::XmppStreamMessage::TLS_FEATURE_REQUEST;
     358             : 
     359        1455 :             ret = strm;
     360             : 
     361        1455 :             XMPP_UTDEBUG(XmppRxStreamTlsRequired, connection->ToUVEKey(),
     362             :                          XMPP_PEER_DIR_IN);
     363             : 
     364        2910 :         } else if (ts.find(sXMPP_STREAM_STARTTLS_O) != string::npos) {
     365             :             XmppStanza::XmppStreamMessage *strm =
     366        1455 :                 new XmppStanza::XmppStreamMessage();
     367        1455 :             strm->strmtype = XmppStanza::XmppStreamMessage::FEATURE_TLS;
     368        1455 :             strm->strmtlstype = XmppStanza::XmppStreamMessage::TLS_START;
     369        1455 :             ret = strm;
     370             : 
     371        1455 :             XMPP_UTDEBUG(XmppRxStreamStartTls, connection->ToUVEKey(),
     372             :                          XMPP_PEER_DIR_IN);
     373             : 
     374        1455 :         } else if (ts.find(sXMPP_STREAM_PROCEED_O) != string::npos) {
     375             :             XmppStanza::XmppStreamMessage *strm =
     376        1456 :                 new XmppStanza::XmppStreamMessage();
     377        1455 :             strm->strmtype = XmppStanza::XmppStreamMessage::FEATURE_TLS;
     378        1455 :             strm->strmtlstype = XmppStanza::XmppStreamMessage::TLS_PROCEED;
     379             : 
     380        1455 :             ret = strm;
     381             : 
     382        1455 :             XMPP_UTDEBUG(XmppRxStreamProceed, connection->ToUVEKey(),
     383             :                          XMPP_PEER_DIR_IN);
     384             :         }
     385        4364 :         goto done;
     386             : 
     387     2516863 :     } else if (ts.find_first_of(sXMPP_VALIDWS) != string::npos) {
     388             : 
     389             :         XmppStanza::XmppMessage *msg =
     390     2516863 :             new XmppStanza::XmppMessage(WHITESPACE_MESSAGE_STANZA);
     391     2516861 :         return msg;
     392             :     } else {
     393           0 :         XMPP_WARNING(XmppBadMessage, connection->ToUVEKey(),
     394             :                      XMPP_PEER_DIR_IN, "Message not supported", ts);
     395             :     }
     396             : 
     397     1691694 : done:
     398             : 
     399     1691694 :     return ret;
     400     4208555 : }
     401             : 
     402       15876 : int XmppProto::SetTo(string &to, XmlBase *doc) {
     403       15876 :     if (!doc) return -1;
     404             : 
     405       15876 :     string ns(sXMPP_STREAM_O);
     406       15876 :     doc->ReadNode(ns);
     407       15876 :     doc->ModifyAttribute("to", to);
     408             : 
     409       15877 :     return 0;
     410       15877 : }
     411             : 
     412       15877 : int XmppProto::SetFrom(string &from, XmlBase *doc) {
     413       15877 :     if (!doc) return -1;
     414             : 
     415       15877 :     string ns(sXMPP_STREAM_O);
     416       15877 :     doc->ReadNode(ns);
     417       15875 :     return doc->ModifyAttribute("from", from);
     418       15875 : }
     419             : 
     420        8054 : int XmppProto::SetXmlns(const string &xmlns, XmlBase *doc) {
     421        8054 :     if (!doc)
     422           0 :         return -1;
     423             : 
     424        8054 :     string ns(sXMPP_STREAM_O);
     425        8054 :     doc->ReadNode(ns);
     426        8054 :     return doc->ModifyAttribute("xmlns", xmlns);
     427        8054 : }
     428             : 
     429     1687355 : const char *XmppProto::GetTo(XmlBase *doc) {
     430     1687355 :     if (!doc) return NULL;
     431             : 
     432     1687355 :     string tmp("to");
     433     1687353 :     return doc->ReadAttrib(tmp);
     434     1687354 : }
     435             : 
     436     1687360 : const char *XmppProto::GetFrom(XmlBase *doc) {
     437     1687360 :     if (!doc) return NULL;
     438             : 
     439     1687360 :     string tmp("from");
     440     1687355 :     return doc->ReadAttrib(tmp);
     441     1687363 : }
     442             : 
     443       15717 : const char *XmppProto::GetXmlns(XmlBase *doc) {
     444       15717 :     if (!doc)
     445           0 :         return NULL;
     446             : 
     447       15717 :     string tmp("xmlns");
     448       15716 :     return doc->ReadAttrib(tmp);
     449       15718 : }
     450             : 
     451       98544 : const char *XmppProto::GetId(XmlBase *doc) {
     452       98544 :     if (!doc) return NULL;
     453             : 
     454       98544 :     string tmp("id");
     455       98545 :     return doc->ReadAttrib(tmp);
     456       98547 : }
     457             : 
     458       98547 : const char *XmppProto::GetType(XmlBase *doc) {
     459       98547 :     if (!doc) return NULL;
     460             : 
     461       98547 :     string tmp("type");
     462       98548 :     return doc->ReadAttrib(tmp);
     463       98547 : }
     464             : 
     465       98546 : const char *XmppProto::GetAction(XmlBase *doc, const string &str) {
     466       98546 :     if (!doc) return NULL;
     467             : 
     468       98546 :     if (str.compare("set") == 0) {
     469       98533 :         doc->ReadNode("pubsub");
     470       98527 :         return(doc->ReadChildNodeName());
     471          15 :     } else if (str.compare("get") == 0) {
     472             :     }
     473             : 
     474          15 :     return(NULL);
     475             : }
     476             : 
     477      197068 : const char *XmppProto::GetNode(XmlBase *doc, const string &str) {
     478      197068 :     if (!doc) return NULL;
     479             : 
     480      197068 :     if (!str.empty()) {
     481      197054 :         return(doc->ReadAttrib("node"));
     482             :     }
     483             : 
     484          15 :     return(NULL);
     485             : }
     486             : 
     487       68959 : const char *XmppProto::GetAsNode(XmlBase *doc) {
     488       68959 :     if (!doc) return NULL;
     489             : 
     490       68959 :     const char *node = doc->ReadNode("associate");
     491       68958 :     if (node != NULL) {
     492       54601 :         return(doc->ReadAttrib("node"));
     493             :     }
     494             : 
     495       14357 :     return(NULL);
     496             : }
     497             : 
     498       28686 : const char *XmppProto::GetDsNode(XmlBase *doc) {
     499       28686 :     if (!doc) return NULL;
     500             : 
     501       28686 :     const char *node = doc->ReadNode("dissociate");
     502       28686 :     if (node != NULL) {
     503       28658 :         return(doc->ReadAttrib("node"));
     504             :     }
     505             : 
     506          28 :     return(NULL);
     507             : }

Generated by: LCOV version 1.14