Coverage Report

Created: 2025-08-24 06:43

/src/mosquitto/libcommon/property_common.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
Copyright (c) 2018-2021 Roger Light <roger@atchoo.org>
3
4
All rights reserved. This program and the accompanying materials
5
are made available under the terms of the Eclipse Public License 2.0
6
and Eclipse Distribution License v1.0 which accompany this distribution.
7
8
The Eclipse Public License is available at
9
   https://www.eclipse.org/legal/epl-2.0/
10
and the Eclipse Distribution License is available at
11
  http://www.eclipse.org/org/documents/edl-v10.php.
12
13
SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
14
15
Contributors:
16
   Roger Light - initial implementation and documentation.
17
*/
18
19
#include "config.h"
20
21
#include <errno.h>
22
#include <stdlib.h>
23
#include <string.h>
24
25
#ifndef WIN32
26
#  include <strings.h>
27
#endif
28
29
#include "mosquitto.h"
30
#include "property_common.h"
31
32
33
void mosquitto_property_free(mosquitto_property **property)
34
25.7M
{
35
25.7M
  if(!property || !(*property)) return;
36
37
25.7M
  switch((*property)->property_type){
38
958k
    case MQTT_PROP_TYPE_STRING:
39
958k
      mosquitto_FREE((*property)->value.s.v);
40
958k
      break;
41
42
1.81M
    case MQTT_PROP_TYPE_BINARY:
43
1.81M
      mosquitto_FREE((*property)->value.bin.v);
44
1.81M
      break;
45
46
14.3k
    case MQTT_PROP_TYPE_STRING_PAIR:
47
14.3k
      mosquitto_FREE((*property)->name.v);
48
14.3k
      mosquitto_FREE((*property)->value.s.v);
49
14.3k
      break;
50
51
18.9M
    case MQTT_PROP_TYPE_BYTE:
52
20.9M
    case MQTT_PROP_TYPE_INT16:
53
21.6M
    case MQTT_PROP_TYPE_INT32:
54
23.0M
    case MQTT_PROP_TYPE_VARINT:
55
      /* Nothing to free */
56
23.0M
      break;
57
25.7M
  }
58
59
25.7M
  mosquitto_FREE(*property);
60
25.7M
}
61
62
63
BROKER_EXPORT void mosquitto_property_free_all(mosquitto_property **property)
64
296k
{
65
296k
  mosquitto_property *p, *next;
66
67
296k
  if(!property) return;
68
69
296k
  p = *property;
70
26.0M
  while(p){
71
25.7M
    next = p->next;
72
25.7M
    mosquitto_property_free(&p);
73
25.7M
    p = next;
74
25.7M
  }
75
296k
  *property = NULL;
76
296k
}
77
78
79
unsigned int mosquitto_property_get_length(const mosquitto_property *property)
80
1.98k
{
81
1.98k
  if(!property) return 0;
82
83
1.98k
  switch(property->property_type){
84
1.98k
    case MQTT_PROP_TYPE_BYTE:
85
1.98k
      return 2; /* 1 (identifier) + 1 byte */
86
87
0
    case MQTT_PROP_TYPE_INT16:
88
0
      return 3; /* 1 (identifier) + 2 bytes */
89
90
0
    case MQTT_PROP_TYPE_INT32:
91
0
      return 5; /* 1 (identifier) + 4 bytes */
92
93
0
    case MQTT_PROP_TYPE_VARINT:
94
0
      if(property->value.varint < 128){
95
0
        return 2;
96
0
      }else if(property->value.varint < 16384){
97
0
        return 3;
98
0
      }else if(property->value.varint < 2097152){
99
0
        return 4;
100
0
      }else if(property->value.varint < 268435456){
101
0
        return 5;
102
0
      }else{
103
0
        return 0;
104
0
      }
105
106
0
    case MQTT_PROP_TYPE_BINARY:
107
0
      return 3U + property->value.bin.len; /* 1 + 2 bytes (len) + X bytes (payload) */
108
109
0
    case MQTT_PROP_TYPE_STRING:
110
0
      return 3U + property->value.s.len; /* 1 + 2 bytes (len) + X bytes (string) */
111
112
0
    case MQTT_PROP_TYPE_STRING_PAIR:
113
0
      return 5U + property->value.s.len + property->name.len; /* 1 + 2*(2 bytes (len) + X bytes (string))*/
114
115
0
    default:
116
0
      return 0;
117
1.98k
  }
118
0
  return 0;
119
1.98k
}
120
121
122
unsigned int mosquitto_property_get_length_all(const mosquitto_property *property)
123
2.34k
{
124
2.34k
  const mosquitto_property *p;
125
2.34k
  unsigned int len = 0;
126
127
2.34k
  p = property;
128
4.33k
  while(p){
129
1.98k
    len += mosquitto_property_get_length(p);
130
1.98k
    p = p->next;
131
1.98k
  }
132
2.34k
  return len;
133
2.34k
}
134
135
136
BROKER_EXPORT int mosquitto_property_check_command(int command, int identifier)
137
20.0k
{
138
20.0k
  switch(identifier){
139
1.80k
    case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR:
140
2.65k
    case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL:
141
4.24k
    case MQTT_PROP_CONTENT_TYPE:
142
5.81k
    case MQTT_PROP_RESPONSE_TOPIC:
143
7.27k
    case MQTT_PROP_CORRELATION_DATA:
144
7.27k
      if(command != CMD_PUBLISH && command != CMD_WILL){
145
236
        return MOSQ_ERR_PROTOCOL;
146
236
      }
147
7.03k
      break;
148
149
7.03k
    case MQTT_PROP_SUBSCRIPTION_IDENTIFIER:
150
1.74k
      if(command != CMD_PUBLISH && command != CMD_SUBSCRIBE){
151
25
        return MOSQ_ERR_PROTOCOL;
152
25
      }
153
1.71k
      break;
154
155
1.71k
    case MQTT_PROP_SESSION_EXPIRY_INTERVAL:
156
91
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_DISCONNECT){
157
17
        return MOSQ_ERR_PROTOCOL;
158
17
      }
159
74
      break;
160
161
169
    case MQTT_PROP_AUTHENTICATION_METHOD:
162
272
    case MQTT_PROP_AUTHENTICATION_DATA:
163
272
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_AUTH){
164
49
        return MOSQ_ERR_PROTOCOL;
165
49
      }
166
223
      break;
167
168
223
    case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER:
169
72
    case MQTT_PROP_SERVER_KEEP_ALIVE:
170
111
    case MQTT_PROP_RESPONSE_INFORMATION:
171
154
    case MQTT_PROP_MAXIMUM_QOS:
172
198
    case MQTT_PROP_RETAIN_AVAILABLE:
173
245
    case MQTT_PROP_WILDCARD_SUB_AVAILABLE:
174
285
    case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE:
175
328
    case MQTT_PROP_SHARED_SUB_AVAILABLE:
176
328
      if(command != CMD_CONNACK){
177
168
        return MOSQ_ERR_PROTOCOL;
178
168
      }
179
160
      break;
180
181
160
    case MQTT_PROP_WILL_DELAY_INTERVAL:
182
27
      if(command != CMD_WILL){
183
14
        return MOSQ_ERR_PROTOCOL;
184
14
      }
185
13
      break;
186
187
70
    case MQTT_PROP_REQUEST_PROBLEM_INFORMATION:
188
143
    case MQTT_PROP_REQUEST_RESPONSE_INFORMATION:
189
143
      if(command != CMD_CONNECT){
190
34
        return MOSQ_ERR_PROTOCOL;
191
34
      }
192
109
      break;
193
194
109
    case MQTT_PROP_SERVER_REFERENCE:
195
61
      if(command != CMD_CONNACK && command != CMD_DISCONNECT){
196
33
        return MOSQ_ERR_PROTOCOL;
197
33
      }
198
28
      break;
199
200
127
    case MQTT_PROP_REASON_STRING:
201
127
      if(command == CMD_CONNECT || command == CMD_PUBLISH || command == CMD_SUBSCRIBE || command == CMD_UNSUBSCRIBE){
202
34
        return MOSQ_ERR_PROTOCOL;
203
34
      }
204
93
      break;
205
206
167
    case MQTT_PROP_RECEIVE_MAXIMUM:
207
306
    case MQTT_PROP_TOPIC_ALIAS_MAXIMUM:
208
801
    case MQTT_PROP_MAXIMUM_PACKET_SIZE:
209
801
      if(command != CMD_CONNECT && command != CMD_CONNACK){
210
439
        return MOSQ_ERR_PROTOCOL;
211
439
      }
212
362
      break;
213
214
1.47k
    case MQTT_PROP_TOPIC_ALIAS:
215
1.47k
      if(command != CMD_PUBLISH){
216
41
        return MOSQ_ERR_PROTOCOL;
217
41
      }
218
1.43k
      break;
219
220
7.75k
    case MQTT_PROP_USER_PROPERTY:
221
7.75k
      break;
222
223
0
    default:
224
0
      return MOSQ_ERR_PROTOCOL;
225
20.0k
  }
226
19.0k
  return MOSQ_ERR_SUCCESS;
227
20.0k
}
228
229
230
BROKER_EXPORT const char *mosquitto_property_identifier_to_string(int identifier)
231
0
{
232
0
  switch(identifier){
233
0
    case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR:
234
0
      return "payload-format-indicator";
235
0
    case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL:
236
0
      return "message-expiry-interval";
237
0
    case MQTT_PROP_CONTENT_TYPE:
238
0
      return "content-type";
239
0
    case MQTT_PROP_RESPONSE_TOPIC:
240
0
      return "response-topic";
241
0
    case MQTT_PROP_CORRELATION_DATA:
242
0
      return "correlation-data";
243
0
    case MQTT_PROP_SUBSCRIPTION_IDENTIFIER:
244
0
      return "subscription-identifier";
245
0
    case MQTT_PROP_SESSION_EXPIRY_INTERVAL:
246
0
      return "session-expiry-interval";
247
0
    case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER:
248
0
      return "assigned-client-identifier";
249
0
    case MQTT_PROP_SERVER_KEEP_ALIVE:
250
0
      return "server-keep-alive";
251
0
    case MQTT_PROP_AUTHENTICATION_METHOD:
252
0
      return "authentication-method";
253
0
    case MQTT_PROP_AUTHENTICATION_DATA:
254
0
      return "authentication-data";
255
0
    case MQTT_PROP_REQUEST_PROBLEM_INFORMATION:
256
0
      return "request-problem-information";
257
0
    case MQTT_PROP_WILL_DELAY_INTERVAL:
258
0
      return "will-delay-interval";
259
0
    case MQTT_PROP_REQUEST_RESPONSE_INFORMATION:
260
0
      return "request-response-information";
261
0
    case MQTT_PROP_RESPONSE_INFORMATION:
262
0
      return "response-information";
263
0
    case MQTT_PROP_SERVER_REFERENCE:
264
0
      return "server-reference";
265
0
    case MQTT_PROP_REASON_STRING:
266
0
      return "reason-string";
267
0
    case MQTT_PROP_RECEIVE_MAXIMUM:
268
0
      return "receive-maximum";
269
0
    case MQTT_PROP_TOPIC_ALIAS_MAXIMUM:
270
0
      return "topic-alias-maximum";
271
0
    case MQTT_PROP_TOPIC_ALIAS:
272
0
      return "topic-alias";
273
0
    case MQTT_PROP_MAXIMUM_QOS:
274
0
      return "maximum-qos";
275
0
    case MQTT_PROP_RETAIN_AVAILABLE:
276
0
      return "retain-available";
277
0
    case MQTT_PROP_USER_PROPERTY:
278
0
      return "user-property";
279
0
    case MQTT_PROP_MAXIMUM_PACKET_SIZE:
280
0
      return "maximum-packet-size";
281
0
    case MQTT_PROP_WILDCARD_SUB_AVAILABLE:
282
0
      return "wildcard-subscription-available";
283
0
    case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE:
284
0
      return "subscription-identifier-available";
285
0
    case MQTT_PROP_SHARED_SUB_AVAILABLE:
286
0
      return "shared-subscription-available";
287
0
    default:
288
0
      return NULL;
289
0
  }
290
0
}
291
292
293
BROKER_EXPORT int mosquitto_string_to_property_info(const char *propname, int *identifier, int *type)
294
0
{
295
0
  if(!propname) return MOSQ_ERR_INVAL;
296
297
0
  if(!strcasecmp(propname, "payload-format-indicator")){
298
0
    *identifier = MQTT_PROP_PAYLOAD_FORMAT_INDICATOR;
299
0
    *type = MQTT_PROP_TYPE_BYTE;
300
0
  }else if(!strcasecmp(propname, "message-expiry-interval")){
301
0
    *identifier = MQTT_PROP_MESSAGE_EXPIRY_INTERVAL;
302
0
    *type = MQTT_PROP_TYPE_INT32;
303
0
  }else if(!strcasecmp(propname, "content-type")){
304
0
    *identifier = MQTT_PROP_CONTENT_TYPE;
305
0
    *type = MQTT_PROP_TYPE_STRING;
306
0
  }else if(!strcasecmp(propname, "response-topic")){
307
0
    *identifier = MQTT_PROP_RESPONSE_TOPIC;
308
0
    *type = MQTT_PROP_TYPE_STRING;
309
0
  }else if(!strcasecmp(propname, "correlation-data")){
310
0
    *identifier = MQTT_PROP_CORRELATION_DATA;
311
0
    *type = MQTT_PROP_TYPE_BINARY;
312
0
  }else if(!strcasecmp(propname, "subscription-identifier")){
313
0
    *identifier = MQTT_PROP_SUBSCRIPTION_IDENTIFIER;
314
0
    *type = MQTT_PROP_TYPE_VARINT;
315
0
  }else if(!strcasecmp(propname, "session-expiry-interval")){
316
0
    *identifier = MQTT_PROP_SESSION_EXPIRY_INTERVAL;
317
0
    *type = MQTT_PROP_TYPE_INT32;
318
0
  }else if(!strcasecmp(propname, "assigned-client-identifier")){
319
0
    *identifier = MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER;
320
0
    *type = MQTT_PROP_TYPE_STRING;
321
0
  }else if(!strcasecmp(propname, "server-keep-alive")){
322
0
    *identifier = MQTT_PROP_SERVER_KEEP_ALIVE;
323
0
    *type = MQTT_PROP_TYPE_INT16;
324
0
  }else if(!strcasecmp(propname, "authentication-method")){
325
0
    *identifier = MQTT_PROP_AUTHENTICATION_METHOD;
326
0
    *type = MQTT_PROP_TYPE_STRING;
327
0
  }else if(!strcasecmp(propname, "authentication-data")){
328
0
    *identifier = MQTT_PROP_AUTHENTICATION_DATA;
329
0
    *type = MQTT_PROP_TYPE_BINARY;
330
0
  }else if(!strcasecmp(propname, "request-problem-information")){
331
0
    *identifier = MQTT_PROP_REQUEST_PROBLEM_INFORMATION;
332
0
    *type = MQTT_PROP_TYPE_BYTE;
333
0
  }else if(!strcasecmp(propname, "will-delay-interval")){
334
0
    *identifier = MQTT_PROP_WILL_DELAY_INTERVAL;
335
0
    *type = MQTT_PROP_TYPE_INT32;
336
0
  }else if(!strcasecmp(propname, "request-response-information")){
337
0
    *identifier = MQTT_PROP_REQUEST_RESPONSE_INFORMATION;
338
0
    *type = MQTT_PROP_TYPE_BYTE;
339
0
  }else if(!strcasecmp(propname, "response-information")){
340
0
    *identifier = MQTT_PROP_RESPONSE_INFORMATION;
341
0
    *type = MQTT_PROP_TYPE_STRING;
342
0
  }else if(!strcasecmp(propname, "server-reference")){
343
0
    *identifier = MQTT_PROP_SERVER_REFERENCE;
344
0
    *type = MQTT_PROP_TYPE_STRING;
345
0
  }else if(!strcasecmp(propname, "reason-string")){
346
0
    *identifier = MQTT_PROP_REASON_STRING;
347
0
    *type = MQTT_PROP_TYPE_STRING;
348
0
  }else if(!strcasecmp(propname, "receive-maximum")){
349
0
    *identifier = MQTT_PROP_RECEIVE_MAXIMUM;
350
0
    *type = MQTT_PROP_TYPE_INT16;
351
0
  }else if(!strcasecmp(propname, "topic-alias-maximum")){
352
0
    *identifier = MQTT_PROP_TOPIC_ALIAS_MAXIMUM;
353
0
    *type = MQTT_PROP_TYPE_INT16;
354
0
  }else if(!strcasecmp(propname, "topic-alias")){
355
0
    *identifier = MQTT_PROP_TOPIC_ALIAS;
356
0
    *type = MQTT_PROP_TYPE_INT16;
357
0
  }else if(!strcasecmp(propname, "maximum-qos")){
358
0
    *identifier = MQTT_PROP_MAXIMUM_QOS;
359
0
    *type = MQTT_PROP_TYPE_BYTE;
360
0
  }else if(!strcasecmp(propname, "retain-available")){
361
0
    *identifier = MQTT_PROP_RETAIN_AVAILABLE;
362
0
    *type = MQTT_PROP_TYPE_BYTE;
363
0
  }else if(!strcasecmp(propname, "user-property")){
364
0
    *identifier = MQTT_PROP_USER_PROPERTY;
365
0
    *type = MQTT_PROP_TYPE_STRING_PAIR;
366
0
  }else if(!strcasecmp(propname, "maximum-packet-size")){
367
0
    *identifier = MQTT_PROP_MAXIMUM_PACKET_SIZE;
368
0
    *type = MQTT_PROP_TYPE_INT32;
369
0
  }else if(!strcasecmp(propname, "wildcard-subscription-available")){
370
0
    *identifier = MQTT_PROP_WILDCARD_SUB_AVAILABLE;
371
0
    *type = MQTT_PROP_TYPE_BYTE;
372
0
  }else if(!strcasecmp(propname, "subscription-identifier-available")){
373
0
    *identifier = MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE;
374
0
    *type = MQTT_PROP_TYPE_BYTE;
375
0
  }else if(!strcasecmp(propname, "shared-subscription-available")){
376
0
    *identifier = MQTT_PROP_SHARED_SUB_AVAILABLE;
377
0
    *type = MQTT_PROP_TYPE_BYTE;
378
0
  }else{
379
0
    return MOSQ_ERR_INVAL;
380
0
  }
381
0
  return MOSQ_ERR_SUCCESS;
382
0
}
383
384
385
static void property__add(mosquitto_property **proplist, struct mqtt5__property *prop)
386
993
{
387
993
  mosquitto_property *p;
388
389
993
  if(!(*proplist)){
390
990
    *proplist = prop;
391
990
  }
392
393
993
  p = *proplist;
394
993
  while(p->next){
395
0
    p = p->next;
396
0
  }
397
993
  p->next = prop;
398
993
  prop->next = NULL;
399
993
}
400
401
402
BROKER_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value)
403
993
{
404
993
  mosquitto_property *prop;
405
406
993
  if(!proplist) return MOSQ_ERR_INVAL;
407
993
  if(identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
408
993
      && identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
409
993
      && identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
410
993
      && identifier != MQTT_PROP_MAXIMUM_QOS
411
993
      && identifier != MQTT_PROP_RETAIN_AVAILABLE
412
993
      && identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
413
993
      && identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
414
993
      && identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
415
0
    return MOSQ_ERR_INVAL;
416
0
  }
417
418
993
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
419
993
  if(!prop) return MOSQ_ERR_NOMEM;
420
421
993
  prop->client_generated = true;
422
993
  prop->identifier = identifier;
423
993
  prop->value.i8 = value;
424
993
  prop->property_type = MQTT_PROP_TYPE_BYTE;
425
426
993
  property__add(proplist, prop);
427
993
  return MOSQ_ERR_SUCCESS;
428
993
}
429
430
431
BROKER_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value)
432
0
{
433
0
  mosquitto_property *prop;
434
435
0
  if(!proplist) return MOSQ_ERR_INVAL;
436
0
  if(identifier != MQTT_PROP_SERVER_KEEP_ALIVE
437
0
      && identifier != MQTT_PROP_RECEIVE_MAXIMUM
438
0
      && identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
439
0
      && identifier != MQTT_PROP_TOPIC_ALIAS){
440
0
    return MOSQ_ERR_INVAL;
441
0
  }
442
443
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
444
0
  if(!prop) return MOSQ_ERR_NOMEM;
445
446
0
  prop->client_generated = true;
447
0
  prop->identifier = identifier;
448
0
  prop->value.i16 = value;
449
0
  prop->property_type = MQTT_PROP_TYPE_INT16;
450
451
0
  property__add(proplist, prop);
452
0
  return MOSQ_ERR_SUCCESS;
453
0
}
454
455
456
BROKER_EXPORT int mosquitto_property_add_int32(mosquitto_property **proplist, int identifier, uint32_t value)
457
0
{
458
0
  mosquitto_property *prop;
459
460
0
  if(!proplist) return MOSQ_ERR_INVAL;
461
0
  if(identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
462
0
      && identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
463
0
      && identifier != MQTT_PROP_WILL_DELAY_INTERVAL
464
0
      && identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
465
466
0
    return MOSQ_ERR_INVAL;
467
0
  }
468
469
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
470
0
  if(!prop) return MOSQ_ERR_NOMEM;
471
472
0
  prop->client_generated = true;
473
0
  prop->identifier = identifier;
474
0
  prop->value.i32 = value;
475
0
  prop->property_type = MQTT_PROP_TYPE_INT32;
476
477
0
  property__add(proplist, prop);
478
0
  return MOSQ_ERR_SUCCESS;
479
0
}
480
481
482
BROKER_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value)
483
0
{
484
0
  mosquitto_property *prop;
485
486
0
  if(!proplist || value > 268435455) return MOSQ_ERR_INVAL;
487
0
  if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER) return MOSQ_ERR_INVAL;
488
489
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
490
0
  if(!prop) return MOSQ_ERR_NOMEM;
491
492
0
  prop->client_generated = true;
493
0
  prop->identifier = identifier;
494
0
  prop->value.varint = value;
495
0
  prop->property_type = MQTT_PROP_TYPE_VARINT;
496
497
0
  property__add(proplist, prop);
498
0
  return MOSQ_ERR_SUCCESS;
499
0
}
500
501
502
BROKER_EXPORT int mosquitto_property_add_binary(mosquitto_property **proplist, int identifier, const void *value, uint16_t len)
503
0
{
504
0
  mosquitto_property *prop;
505
506
0
  if(!proplist) return MOSQ_ERR_INVAL;
507
0
  if(identifier != MQTT_PROP_CORRELATION_DATA
508
0
      && identifier != MQTT_PROP_AUTHENTICATION_DATA){
509
510
0
    return MOSQ_ERR_INVAL;
511
0
  }
512
513
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
514
0
  if(!prop) return MOSQ_ERR_NOMEM;
515
516
0
  prop->client_generated = true;
517
0
  prop->identifier = identifier;
518
0
  prop->property_type = MQTT_PROP_TYPE_BINARY;
519
520
0
  if(len){
521
0
    prop->value.bin.v = mosquitto_malloc(len);
522
0
    if(!prop->value.bin.v){
523
0
      mosquitto_FREE(prop);
524
0
      return MOSQ_ERR_NOMEM;
525
0
    }
526
527
0
    memcpy(prop->value.bin.v, value, len);
528
0
    prop->value.bin.len = len;
529
0
  }
530
531
0
  property__add(proplist, prop);
532
0
  return MOSQ_ERR_SUCCESS;
533
0
}
534
535
536
BROKER_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value)
537
0
{
538
0
  mosquitto_property *prop;
539
0
  size_t slen = 0;
540
541
0
  if(!proplist) return MOSQ_ERR_INVAL;
542
0
  if(value){
543
0
    slen = strlen(value);
544
0
    if(mosquitto_validate_utf8(value, (int)slen)) return MOSQ_ERR_MALFORMED_UTF8;
545
0
  }
546
547
0
  if(identifier != MQTT_PROP_CONTENT_TYPE
548
0
      && identifier != MQTT_PROP_RESPONSE_TOPIC
549
0
      && identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
550
0
      && identifier != MQTT_PROP_AUTHENTICATION_METHOD
551
0
      && identifier != MQTT_PROP_RESPONSE_INFORMATION
552
0
      && identifier != MQTT_PROP_SERVER_REFERENCE
553
0
      && identifier != MQTT_PROP_REASON_STRING){
554
555
0
    return MOSQ_ERR_INVAL;
556
0
  }
557
558
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
559
0
  if(!prop) return MOSQ_ERR_NOMEM;
560
561
0
  prop->client_generated = true;
562
0
  prop->identifier = identifier;
563
0
  prop->property_type = MQTT_PROP_TYPE_STRING;
564
0
  if(value && slen > 0){
565
0
    prop->value.s.v = mosquitto_strdup(value);
566
0
    if(!prop->value.s.v){
567
0
      mosquitto_FREE(prop);
568
0
      return MOSQ_ERR_NOMEM;
569
0
    }
570
0
    prop->value.s.len = (uint16_t)slen;
571
0
  }
572
573
0
  property__add(proplist, prop);
574
0
  return MOSQ_ERR_SUCCESS;
575
0
}
576
577
578
BROKER_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value)
579
0
{
580
0
  mosquitto_property *prop;
581
0
  size_t slen_name = 0, slen_value = 0;
582
583
0
  if(!proplist) return MOSQ_ERR_INVAL;
584
0
  if(identifier != MQTT_PROP_USER_PROPERTY) return MOSQ_ERR_INVAL;
585
0
  if(name){
586
0
    slen_name = strlen(name);
587
0
    if(mosquitto_validate_utf8(name, (int)slen_name)) return MOSQ_ERR_MALFORMED_UTF8;
588
0
  }
589
0
  if(value){
590
0
    if(mosquitto_validate_utf8(value, (int)slen_value)) return MOSQ_ERR_MALFORMED_UTF8;
591
0
  }
592
593
0
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
594
0
  if(!prop) return MOSQ_ERR_NOMEM;
595
596
0
  prop->client_generated = true;
597
0
  prop->identifier = identifier;
598
0
  prop->property_type = MQTT_PROP_TYPE_STRING_PAIR;
599
600
0
  if(name){
601
0
    prop->name.v = mosquitto_strdup(name);
602
0
    if(!prop->name.v){
603
0
      mosquitto_FREE(prop);
604
0
      return MOSQ_ERR_NOMEM;
605
0
    }
606
0
    prop->name.len = (uint16_t)strlen(name);
607
0
  }
608
609
0
  if(value){
610
0
    prop->value.s.v = mosquitto_strdup(value);
611
0
    if(!prop->value.s.v){
612
0
      mosquitto_FREE(prop->name.v);
613
0
      mosquitto_FREE(prop);
614
0
      return MOSQ_ERR_NOMEM;
615
0
    }
616
0
    prop->value.s.len = (uint16_t)strlen(value);
617
0
  }
618
619
0
  property__add(proplist, prop);
620
0
  return MOSQ_ERR_SUCCESS;
621
0
}
622
623
BROKER_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties)
624
10.4k
{
625
10.4k
  const mosquitto_property *p, *tail;
626
10.4k
  int rc;
627
628
10.4k
  p = properties;
629
630
29.3k
  while(p){
631
    /* Validity checks */
632
20.2k
    if(p->identifier == MQTT_PROP_REQUEST_PROBLEM_INFORMATION
633
20.2k
        || p->identifier == MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
634
20.2k
        || p->identifier == MQTT_PROP_REQUEST_RESPONSE_INFORMATION
635
20.2k
        || p->identifier == MQTT_PROP_MAXIMUM_QOS
636
20.2k
        || p->identifier == MQTT_PROP_RETAIN_AVAILABLE
637
20.2k
        || p->identifier == MQTT_PROP_WILDCARD_SUB_AVAILABLE
638
20.2k
        || p->identifier == MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
639
20.2k
        || p->identifier == MQTT_PROP_SHARED_SUB_AVAILABLE){
640
641
2.26k
      if(p->value.i8 > 1){
642
107
        return MOSQ_ERR_PROTOCOL;
643
107
      }
644
17.9k
    }else if(p->identifier == MQTT_PROP_MAXIMUM_PACKET_SIZE){
645
504
      if( p->value.i32 == 0){
646
9
        return MOSQ_ERR_PROTOCOL;
647
9
      }
648
17.4k
    }else if(p->identifier == MQTT_PROP_RECEIVE_MAXIMUM
649
17.4k
        || p->identifier == MQTT_PROP_TOPIC_ALIAS){
650
651
1.65k
      if(p->value.i16 == 0){
652
10
        return MOSQ_ERR_PROTOCOL;
653
10
      }
654
15.8k
    }else if(p->identifier == MQTT_PROP_RESPONSE_TOPIC){
655
1.61k
      if(mosquitto_pub_topic_check(p->value.s.v) != MOSQ_ERR_SUCCESS){
656
43
        return MOSQ_ERR_PROTOCOL;
657
43
      }
658
1.61k
    }
659
660
    /* Check for properties on incorrect commands */
661
20.0k
    rc = mosquitto_property_check_command(command, p->identifier);
662
20.0k
    if(rc) return rc;
663
664
    /* Check for duplicates */
665
19.0k
    if(p->identifier != MQTT_PROP_USER_PROPERTY){
666
11.2k
      tail = p->next;
667
31.5k
      while(tail){
668
20.3k
        if(p->identifier == tail->identifier){
669
25
          return MOSQ_ERR_DUPLICATE_PROPERTY;
670
25
        }
671
20.2k
        tail = tail->next;
672
20.2k
      }
673
11.2k
    }
674
675
18.9k
    p = p->next;
676
18.9k
  }
677
678
9.13k
  return MOSQ_ERR_SUCCESS;
679
10.4k
}
680
681
static const mosquitto_property *property__get_property(const mosquitto_property *proplist, int identifier, bool skip_first)
682
1.12k
{
683
1.12k
  const mosquitto_property *p;
684
1.12k
  bool is_first = true;
685
686
1.12k
  p = proplist;
687
688
8.56k
  while(p){
689
7.80k
    if(p->identifier == identifier){
690
362
      if(!is_first || !skip_first){
691
362
        return p;
692
362
      }
693
0
      is_first = false;
694
0
    }
695
7.43k
    p = p->next;
696
7.43k
  }
697
759
  return NULL;
698
1.12k
}
699
700
701
BROKER_EXPORT int mosquitto_property_identifier(const mosquitto_property *property)
702
16.6k
{
703
16.6k
  if(property == NULL) return 0;
704
705
16.6k
  return property->identifier;
706
16.6k
}
707
708
709
BROKER_EXPORT int mosquitto_property_type(const mosquitto_property *property)
710
0
{
711
0
  if(property == NULL) return 0;
712
713
0
  return property->property_type;
714
0
}
715
716
717
BROKER_EXPORT mosquitto_property *mosquitto_property_next(const mosquitto_property *proplist)
718
16.4k
{
719
16.4k
  if(proplist == NULL) return NULL;
720
721
16.4k
  return proplist->next;
722
16.4k
}
723
724
725
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_byte(const mosquitto_property *proplist, int identifier, uint8_t *value, bool skip_first)
726
266
{
727
266
  const mosquitto_property *p;
728
266
  if(!proplist) return NULL;
729
730
180
  p = property__get_property(proplist, identifier, skip_first);
731
180
  if(!p) return NULL;
732
30
  if(p->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
733
30
      && p->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
734
30
      && p->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
735
30
      && p->identifier != MQTT_PROP_MAXIMUM_QOS
736
30
      && p->identifier != MQTT_PROP_RETAIN_AVAILABLE
737
30
      && p->identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
738
30
      && p->identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
739
30
      && p->identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
740
0
    return NULL;
741
0
  }
742
743
30
  if(value) *value = p->value.i8;
744
745
30
  return p;
746
30
}
747
748
749
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int16(const mosquitto_property *proplist, int identifier, uint16_t *value, bool skip_first)
750
399
{
751
399
  const mosquitto_property *p;
752
399
  if(!proplist) return NULL;
753
754
270
  p = property__get_property(proplist, identifier, skip_first);
755
270
  if(!p) return NULL;
756
89
  if(p->identifier != MQTT_PROP_SERVER_KEEP_ALIVE
757
89
      && p->identifier != MQTT_PROP_RECEIVE_MAXIMUM
758
89
      && p->identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
759
89
      && p->identifier != MQTT_PROP_TOPIC_ALIAS){
760
0
    return NULL;
761
0
  }
762
763
89
  if(value) *value = p->value.i16;
764
765
89
  return p;
766
89
}
767
768
769
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_int32(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first)
770
133
{
771
133
  const mosquitto_property *p;
772
133
  if(!proplist) return NULL;
773
774
90
  p = property__get_property(proplist, identifier, skip_first);
775
90
  if(!p) return NULL;
776
8
  if(p->identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
777
8
      && p->identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
778
8
      && p->identifier != MQTT_PROP_WILL_DELAY_INTERVAL
779
8
      && p->identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
780
781
0
    return NULL;
782
0
  }
783
784
8
  if(value) *value = p->value.i32;
785
786
8
  return p;
787
8
}
788
789
790
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_varint(const mosquitto_property *proplist, int identifier, uint32_t *value, bool skip_first)
791
202
{
792
202
  const mosquitto_property *p;
793
202
  if(!proplist) return NULL;
794
795
98
  p = property__get_property(proplist, identifier, skip_first);
796
98
  if(!p) return NULL;
797
73
  if(p->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
798
0
    return NULL;
799
0
  }
800
801
73
  if(value) *value = p->value.varint;
802
803
73
  return p;
804
73
}
805
806
807
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_binary(const mosquitto_property *proplist, int identifier, void **value, uint16_t *len, bool skip_first)
808
1.00k
{
809
1.00k
  const mosquitto_property *p;
810
1.00k
  if(!proplist || (value && !len) || (!value && len)) return NULL;
811
812
208
  if(value) *value = NULL;
813
814
208
  p = property__get_property(proplist, identifier, skip_first);
815
208
  if(!p) return NULL;
816
47
  if(p->identifier != MQTT_PROP_CORRELATION_DATA
817
47
      && p->identifier != MQTT_PROP_AUTHENTICATION_DATA){
818
819
0
    return NULL;
820
0
  }
821
822
47
  if(value){
823
47
    *len = p->value.bin.len;
824
47
    if(p->value.bin.len){
825
21
      *value = mosquitto_calloc(1, *len + 1U);
826
21
      if(!(*value)) return NULL;
827
828
21
      memcpy(*value, p->value.bin.v, *len);
829
26
    }else{
830
26
      *value = NULL;
831
26
    }
832
47
  }
833
834
47
  return p;
835
47
}
836
837
838
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string(const mosquitto_property *proplist, int identifier, char **value, bool skip_first)
839
1.07k
{
840
1.07k
  const mosquitto_property *p;
841
1.07k
  if(!proplist) return NULL;
842
843
275
  p = property__get_property(proplist, identifier, skip_first);
844
275
  if(!p) return NULL;
845
115
  if(p->identifier != MQTT_PROP_CONTENT_TYPE
846
115
      && p->identifier != MQTT_PROP_RESPONSE_TOPIC
847
115
      && p->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
848
115
      && p->identifier != MQTT_PROP_AUTHENTICATION_METHOD
849
115
      && p->identifier != MQTT_PROP_RESPONSE_INFORMATION
850
115
      && p->identifier != MQTT_PROP_SERVER_REFERENCE
851
115
      && p->identifier != MQTT_PROP_REASON_STRING){
852
853
0
    return NULL;
854
0
  }
855
856
115
  if(value){
857
115
    if(p->value.s.len){
858
79
      *value = mosquitto_calloc(1, (size_t)p->value.s.len+1);
859
79
      if(!(*value)) return NULL;
860
861
79
      memcpy(*value, p->value.s.v, p->value.s.len);
862
79
    }else{
863
36
      *value = NULL;
864
36
    }
865
115
  }
866
867
115
  return p;
868
115
}
869
870
871
BROKER_EXPORT const mosquitto_property *mosquitto_property_read_string_pair(const mosquitto_property *proplist, int identifier, char **name, char **value, bool skip_first)
872
0
{
873
0
  const mosquitto_property *p;
874
0
  if(!proplist) return NULL;
875
876
0
  if(name) *name = NULL;
877
0
  if(value) *value = NULL;
878
879
0
  p = property__get_property(proplist, identifier, skip_first);
880
0
  if(!p) return NULL;
881
0
  if(p->identifier != MQTT_PROP_USER_PROPERTY) return NULL;
882
883
0
  if(name){
884
0
    if(p->name.len){
885
0
      *name = mosquitto_calloc(1, (size_t)p->name.len+1);
886
0
      if(!(*name)) return NULL;
887
0
      memcpy(*name, p->name.v, p->name.len);
888
0
    }else{
889
0
      *name = NULL;
890
0
    }
891
0
  }
892
893
0
  if(value){
894
0
    if(p->value.s.len){
895
0
      *value = mosquitto_calloc(1, (size_t)p->value.s.len+1);
896
0
      if(!(*value)){
897
0
        if(name){
898
0
          mosquitto_FREE(*name);
899
0
        }
900
0
        return NULL;
901
0
      }
902
0
      memcpy(*value, p->value.s.v, p->value.s.len);
903
0
    }else{
904
0
      *value = NULL;
905
0
    }
906
0
  }
907
908
0
  return p;
909
0
}
910
911
912
BROKER_EXPORT int mosquitto_property_remove(mosquitto_property **proplist, const mosquitto_property *property)
913
0
{
914
0
  mosquitto_property *item, *item_prev = NULL;
915
916
0
  if(proplist == NULL || property == NULL){
917
0
    return MOSQ_ERR_INVAL;
918
0
  }
919
920
0
  item = *proplist;
921
0
  while(item){
922
0
    if(item == property){
923
0
      if(item_prev == NULL){
924
0
        *proplist = (*proplist)->next;
925
0
      }else{
926
0
        item_prev->next = item->next;
927
0
      }
928
0
      item->next = NULL;
929
0
      return MOSQ_ERR_SUCCESS;
930
0
    }
931
0
    item_prev = item;
932
0
    item = item->next;
933
0
  }
934
935
0
  return MOSQ_ERR_NOT_FOUND;
936
0
}
937
938
939
BROKER_EXPORT int mosquitto_property_copy_all(mosquitto_property **dest, const mosquitto_property *src)
940
1.10k
{
941
1.10k
  mosquitto_property *pnew, *plast = NULL;
942
943
1.10k
  if(!src) return MOSQ_ERR_SUCCESS;
944
0
  if(!dest) return MOSQ_ERR_INVAL;
945
946
0
  *dest = NULL;
947
948
0
  while(src){
949
0
    pnew = mosquitto_calloc(1, sizeof(mosquitto_property));
950
0
    if(!pnew){
951
0
      mosquitto_property_free_all(dest);
952
0
      return MOSQ_ERR_NOMEM;
953
0
    }
954
0
    if(plast){
955
0
      plast->next = pnew;
956
0
    }else{
957
0
      *dest = pnew;
958
0
    }
959
0
    plast = pnew;
960
961
0
    pnew->client_generated = src->client_generated;
962
0
    pnew->identifier = src->identifier;
963
0
    pnew->property_type = src->property_type;
964
0
    switch(pnew->property_type){
965
0
      case MQTT_PROP_TYPE_BYTE:
966
0
        pnew->value.i8 = src->value.i8;
967
0
        break;
968
969
0
      case MQTT_PROP_TYPE_INT16:
970
0
        pnew->value.i16 = src->value.i16;
971
0
        break;
972
973
0
      case MQTT_PROP_TYPE_INT32:
974
0
        pnew->value.i32 = src->value.i32;
975
0
        break;
976
977
0
      case MQTT_PROP_TYPE_VARINT:
978
0
        pnew->value.varint = src->value.varint;
979
0
        break;
980
981
0
      case MQTT_PROP_TYPE_STRING:
982
0
        pnew->value.s.len = src->value.s.len;
983
0
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char*)mosquitto_calloc(1,1);
984
0
        if(!pnew->value.s.v){
985
0
          mosquitto_property_free_all(dest);
986
0
          return MOSQ_ERR_NOMEM;
987
0
        }
988
0
        break;
989
990
0
      case MQTT_PROP_TYPE_BINARY:
991
0
        pnew->value.bin.len = src->value.bin.len;
992
0
        if(src->value.bin.len){
993
0
          pnew->value.bin.v = mosquitto_malloc(pnew->value.bin.len);
994
0
          if(!pnew->value.bin.v){
995
0
            mosquitto_property_free_all(dest);
996
0
            return MOSQ_ERR_NOMEM;
997
0
          }
998
0
          memcpy(pnew->value.bin.v, src->value.bin.v, pnew->value.bin.len);
999
0
        }
1000
0
        break;
1001
1002
0
      case MQTT_PROP_TYPE_STRING_PAIR:
1003
0
        pnew->value.s.len = src->value.s.len;
1004
0
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char*)mosquitto_calloc(1,1);
1005
0
        if(!pnew->value.s.v){
1006
0
          mosquitto_property_free_all(dest);
1007
0
          return MOSQ_ERR_NOMEM;
1008
0
        }
1009
1010
0
        pnew->name.len = src->name.len;
1011
0
        pnew->name.v = src->name.v ? mosquitto_strdup(src->name.v) : (char*)mosquitto_calloc(1,1);
1012
0
        if(!pnew->name.v){
1013
0
          mosquitto_property_free_all(dest);
1014
0
          return MOSQ_ERR_NOMEM;
1015
0
        }
1016
0
        break;
1017
1018
0
      default:
1019
0
        mosquitto_property_free_all(dest);
1020
0
        return MOSQ_ERR_INVAL;
1021
0
    }
1022
1023
0
    src = mosquitto_property_next(src);
1024
0
  }
1025
1026
0
  return MOSQ_ERR_SUCCESS;
1027
0
}
1028
1029
1030
uint8_t mosquitto_property_byte_value(const mosquitto_property *property)
1031
328
{
1032
328
  if(property && property->property_type == MQTT_PROP_TYPE_BYTE){
1033
328
    return property->value.i8;
1034
328
  }else{
1035
0
    return 0;
1036
0
  }
1037
328
}
1038
1039
1040
uint16_t mosquitto_property_int16_value(const mosquitto_property *property)
1041
191
{
1042
191
  if(property && property->property_type == MQTT_PROP_TYPE_INT16){
1043
191
    return property->value.i16;
1044
191
  }else{
1045
0
    return 0;
1046
0
  }
1047
191
}
1048
1049
1050
uint32_t mosquitto_property_int32_value(const mosquitto_property *property)
1051
237
{
1052
237
  if(property && property->property_type == MQTT_PROP_TYPE_INT32){
1053
237
    return property->value.i32;
1054
237
  }else{
1055
0
    return 0;
1056
0
  }
1057
237
}
1058
1059
1060
uint32_t mosquitto_property_varint_value(const mosquitto_property *property)
1061
1.46k
{
1062
1.46k
  if(property && property->property_type == MQTT_PROP_TYPE_VARINT){
1063
1.46k
    return property->value.varint;
1064
1.46k
  }else{
1065
0
    return 0;
1066
0
  }
1067
1.46k
}
1068
1069
1070
const void *mosquitto_property_binary_value(const mosquitto_property *property)
1071
422
{
1072
422
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1073
422
    return property->value.bin.v;
1074
422
  }else{
1075
0
    return NULL;
1076
0
  }
1077
422
}
1078
1079
1080
uint16_t mosquitto_property_binary_value_length(const mosquitto_property *property)
1081
1.07k
{
1082
1.07k
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1083
1.07k
    return property->value.bin.len;
1084
1.07k
  }else{
1085
0
    return 0;
1086
0
  }
1087
1.07k
}
1088
1089
1090
const char *mosquitto_property_string_value(const mosquitto_property *property)
1091
679
{
1092
679
  if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){
1093
679
    return property->value.s.v;
1094
679
  }else{
1095
0
    return NULL;
1096
0
  }
1097
679
}
1098
1099
1100
uint16_t mosquitto_property_string_value_length(const mosquitto_property *property)
1101
0
{
1102
0
  if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){
1103
0
    return property->value.s.len;
1104
0
  }else{
1105
0
    return 0;
1106
0
  }
1107
0
}
1108
1109
1110
const char *mosquitto_property_string_name(const mosquitto_property *property)
1111
195
{
1112
195
  if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){
1113
195
    return property->name.v;
1114
195
  }else{
1115
0
    return NULL;
1116
0
  }
1117
195
}
1118
1119
1120
uint16_t mosquitto_property_string_name_length(const mosquitto_property *property)
1121
0
{
1122
0
  if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){
1123
0
    return property->name.len;
1124
0
  }else{
1125
0
    return 0;
1126
0
  }
1127
0
}
1128
1129
/* Return the number of bytes we need to add on to the remaining length when
1130
 * encoding these properties. */
1131
unsigned int mosquitto_property_get_remaining_length(const mosquitto_property *props)
1132
1.17k
{
1133
1.17k
  unsigned int proplen, varbytes;
1134
1135
1.17k
  proplen = mosquitto_property_get_length_all(props);
1136
1.17k
  varbytes = mosquitto_varint_bytes(proplen);
1137
1.17k
  return proplen + varbytes;
1138
1.17k
}
1139
1140