Coverage Report

Created: 2026-01-13 07:08

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