Coverage Report

Created: 2026-03-29 06:44

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
34.3M
{
35
34.3M
  if(!property || !(*property)){
36
0
    return;
37
0
  }
38
39
34.3M
  switch((*property)->property_type){
40
1.04M
    case MQTT_PROP_TYPE_STRING:
41
1.04M
      mosquitto_FREE((*property)->value.s.v);
42
1.04M
      break;
43
44
2.55M
    case MQTT_PROP_TYPE_BINARY:
45
2.55M
      mosquitto_FREE((*property)->value.bin.v);
46
2.55M
      break;
47
48
17.3k
    case MQTT_PROP_TYPE_STRING_PAIR:
49
17.3k
      mosquitto_FREE((*property)->name.v);
50
17.3k
      mosquitto_FREE((*property)->value.s.v);
51
17.3k
      break;
52
53
27.5M
    case MQTT_PROP_TYPE_BYTE:
54
29.3M
    case MQTT_PROP_TYPE_INT16:
55
29.9M
    case MQTT_PROP_TYPE_INT32:
56
30.7M
    case MQTT_PROP_TYPE_VARINT:
57
      /* Nothing to free */
58
30.7M
      break;
59
34.3M
  }
60
61
34.3M
  mosquitto_FREE(*property);
62
34.3M
}
63
64
65
BROKER_EXPORT void mosquitto_property_free_all(mosquitto_property **property)
66
134k
{
67
134k
  mosquitto_property *p, *next;
68
69
134k
  if(!property){
70
0
    return;
71
0
  }
72
73
134k
  p = *property;
74
34.4M
  while(p){
75
34.3M
    next = p->next;
76
34.3M
    mosquitto_property_free(&p);
77
34.3M
    p = next;
78
34.3M
  }
79
134k
  *property = NULL;
80
134k
}
81
82
83
unsigned int mosquitto_property_get_length(const mosquitto_property *property)
84
2.34k
{
85
2.34k
  if(!property){
86
0
    return 0;
87
0
  }
88
89
2.34k
  switch(property->property_type){
90
2.34k
    case MQTT_PROP_TYPE_BYTE:
91
2.34k
      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.34k
  }
124
0
  return 0;
125
2.34k
}
126
127
128
unsigned int mosquitto_property_get_length_all(const mosquitto_property *property)
129
2.82k
{
130
2.82k
  const mosquitto_property *p;
131
2.82k
  unsigned int len = 0;
132
133
2.82k
  p = property;
134
5.17k
  while(p){
135
2.34k
    len += mosquitto_property_get_length(p);
136
2.34k
    p = p->next;
137
2.34k
  }
138
2.82k
  return len;
139
2.82k
}
140
141
142
BROKER_EXPORT int mosquitto_property_check_command(int command, int identifier)
143
22.9k
{
144
22.9k
  switch(identifier){
145
2.89k
    case MQTT_PROP_PAYLOAD_FORMAT_INDICATOR:
146
3.83k
    case MQTT_PROP_MESSAGE_EXPIRY_INTERVAL:
147
5.21k
    case MQTT_PROP_CONTENT_TYPE:
148
7.08k
    case MQTT_PROP_RESPONSE_TOPIC:
149
8.85k
    case MQTT_PROP_CORRELATION_DATA:
150
8.85k
      if(command != CMD_PUBLISH && command != CMD_WILL){
151
238
        return MOSQ_ERR_PROTOCOL;
152
238
      }
153
8.61k
      break;
154
155
8.61k
    case MQTT_PROP_SUBSCRIPTION_IDENTIFIER:
156
1.80k
      if(command != CMD_PUBLISH && command != CMD_SUBSCRIBE){
157
31
        return MOSQ_ERR_PROTOCOL;
158
31
      }
159
1.77k
      break;
160
161
1.77k
    case MQTT_PROP_SESSION_EXPIRY_INTERVAL:
162
87
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_DISCONNECT){
163
16
        return MOSQ_ERR_PROTOCOL;
164
16
      }
165
71
      break;
166
167
187
    case MQTT_PROP_AUTHENTICATION_METHOD:
168
300
    case MQTT_PROP_AUTHENTICATION_DATA:
169
300
      if(command != CMD_CONNECT && command != CMD_CONNACK && command != CMD_AUTH){
170
69
        return MOSQ_ERR_PROTOCOL;
171
69
      }
172
231
      break;
173
174
231
    case MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER:
175
80
    case MQTT_PROP_SERVER_KEEP_ALIVE:
176
120
    case MQTT_PROP_RESPONSE_INFORMATION:
177
162
    case MQTT_PROP_MAXIMUM_QOS:
178
199
    case MQTT_PROP_RETAIN_AVAILABLE:
179
241
    case MQTT_PROP_WILDCARD_SUB_AVAILABLE:
180
290
    case MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE:
181
344
    case MQTT_PROP_SHARED_SUB_AVAILABLE:
182
344
      if(command != CMD_CONNACK){
183
186
        return MOSQ_ERR_PROTOCOL;
184
186
      }
185
158
      break;
186
187
158
    case MQTT_PROP_WILL_DELAY_INTERVAL:
188
26
      if(command != CMD_WILL){
189
14
        return MOSQ_ERR_PROTOCOL;
190
14
      }
191
12
      break;
192
193
76
    case MQTT_PROP_REQUEST_PROBLEM_INFORMATION:
194
158
    case MQTT_PROP_REQUEST_RESPONSE_INFORMATION:
195
158
      if(command != CMD_CONNECT){
196
39
        return MOSQ_ERR_PROTOCOL;
197
39
      }
198
119
      break;
199
200
119
    case MQTT_PROP_SERVER_REFERENCE:
201
52
      if(command != CMD_CONNACK && command != CMD_DISCONNECT){
202
26
        return MOSQ_ERR_PROTOCOL;
203
26
      }
204
26
      break;
205
206
141
    case MQTT_PROP_REASON_STRING:
207
141
      if(command == CMD_CONNECT || command == CMD_PUBLISH || command == CMD_SUBSCRIBE || command == CMD_UNSUBSCRIBE){
208
30
        return MOSQ_ERR_PROTOCOL;
209
30
      }
210
111
      break;
211
212
155
    case MQTT_PROP_RECEIVE_MAXIMUM:
213
303
    case MQTT_PROP_TOPIC_ALIAS_MAXIMUM:
214
713
    case MQTT_PROP_MAXIMUM_PACKET_SIZE:
215
713
      if(command != CMD_CONNECT && command != CMD_CONNACK){
216
327
        return MOSQ_ERR_PROTOCOL;
217
327
      }
218
386
      break;
219
220
1.30k
    case MQTT_PROP_TOPIC_ALIAS:
221
1.30k
      if(command != CMD_PUBLISH){
222
48
        return MOSQ_ERR_PROTOCOL;
223
48
      }
224
1.25k
      break;
225
226
9.21k
    case MQTT_PROP_USER_PROPERTY:
227
9.21k
      break;
228
229
0
    default:
230
0
      return MOSQ_ERR_PROTOCOL;
231
22.9k
  }
232
21.9k
  return MOSQ_ERR_SUCCESS;
233
22.9k
}
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
11.5k
{
395
11.5k
  mosquitto_property *p;
396
397
11.5k
  if(!(*proplist)){
398
1.71k
    *proplist = prop;
399
1.71k
  }
400
401
11.5k
  p = *proplist;
402
432k
  while(p->next){
403
420k
    p = p->next;
404
420k
  }
405
11.5k
  p->next = prop;
406
11.5k
  prop->next = NULL;
407
11.5k
}
408
409
410
BROKER_EXPORT int mosquitto_property_add_byte(mosquitto_property **proplist, int identifier, uint8_t value)
411
3.70k
{
412
3.70k
  mosquitto_property *prop;
413
414
3.70k
  if(!proplist){
415
0
    return MOSQ_ERR_INVAL;
416
0
  }
417
3.70k
  if(identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
418
2.91k
      && identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
419
2.72k
      && identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
420
2.52k
      && identifier != MQTT_PROP_MAXIMUM_QOS
421
1.15k
      && identifier != MQTT_PROP_RETAIN_AVAILABLE
422
961
      && identifier != MQTT_PROP_WILDCARD_SUB_AVAILABLE
423
765
      && identifier != MQTT_PROP_SUBSCRIPTION_ID_AVAILABLE
424
571
      && identifier != MQTT_PROP_SHARED_SUB_AVAILABLE){
425
377
    return MOSQ_ERR_INVAL;
426
377
  }
427
428
3.33k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
429
3.33k
  if(!prop){
430
0
    return MOSQ_ERR_NOMEM;
431
0
  }
432
433
3.33k
  prop->client_generated = true;
434
3.33k
  prop->identifier = identifier;
435
3.33k
  prop->value.i8 = value;
436
3.33k
  prop->property_type = MQTT_PROP_TYPE_BYTE;
437
438
3.33k
  property__add(proplist, prop);
439
3.33k
  return MOSQ_ERR_SUCCESS;
440
3.33k
}
441
442
443
BROKER_EXPORT int mosquitto_property_add_int16(mosquitto_property **proplist, int identifier, uint16_t value)
444
1.32k
{
445
1.32k
  mosquitto_property *prop;
446
447
1.32k
  if(!proplist){
448
0
    return MOSQ_ERR_INVAL;
449
0
  }
450
1.32k
  if(identifier != MQTT_PROP_SERVER_KEEP_ALIVE
451
1.07k
      && identifier != MQTT_PROP_RECEIVE_MAXIMUM
452
883
      && identifier != MQTT_PROP_TOPIC_ALIAS_MAXIMUM
453
560
      && identifier != MQTT_PROP_TOPIC_ALIAS){
454
321
    return MOSQ_ERR_INVAL;
455
321
  }
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.47k
{
474
1.47k
  mosquitto_property *prop;
475
476
1.47k
  if(!proplist){
477
0
    return MOSQ_ERR_INVAL;
478
0
  }
479
1.47k
  if(identifier != MQTT_PROP_MESSAGE_EXPIRY_INTERVAL
480
1.05k
      && identifier != MQTT_PROP_SESSION_EXPIRY_INTERVAL
481
856
      && identifier != MQTT_PROP_WILL_DELAY_INTERVAL
482
662
      && identifier != MQTT_PROP_MAXIMUM_PACKET_SIZE){
483
484
468
    return MOSQ_ERR_INVAL;
485
468
  }
486
487
1.00k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
488
1.00k
  if(!prop){
489
0
    return MOSQ_ERR_NOMEM;
490
0
  }
491
492
1.00k
  prop->client_generated = true;
493
1.00k
  prop->identifier = identifier;
494
1.00k
  prop->value.i32 = value;
495
1.00k
  prop->property_type = MQTT_PROP_TYPE_INT32;
496
497
1.00k
  property__add(proplist, prop);
498
1.00k
  return MOSQ_ERR_SUCCESS;
499
1.00k
}
500
501
502
BROKER_EXPORT int mosquitto_property_add_varint(mosquitto_property **proplist, int identifier, uint32_t value)
503
792
{
504
792
  mosquitto_property *prop;
505
506
792
  if(!proplist || value > MQTT_MAX_PAYLOAD){
507
200
    return MOSQ_ERR_INVAL;
508
200
  }
509
592
  if(identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
510
332
    return MOSQ_ERR_INVAL;
511
332
  }
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
2.65k
{
530
2.65k
  mosquitto_property *prop;
531
532
2.65k
  if(!proplist){
533
0
    return MOSQ_ERR_INVAL;
534
0
  }
535
2.65k
  if(identifier != MQTT_PROP_CORRELATION_DATA
536
625
      && identifier != MQTT_PROP_AUTHENTICATION_DATA){
537
538
429
    return MOSQ_ERR_INVAL;
539
429
  }
540
541
2.22k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
542
2.22k
  if(!prop){
543
0
    return MOSQ_ERR_NOMEM;
544
0
  }
545
546
2.22k
  prop->client_generated = true;
547
2.22k
  prop->identifier = identifier;
548
2.22k
  prop->property_type = MQTT_PROP_TYPE_BINARY;
549
550
2.22k
  if(len){
551
1.46k
    prop->value.bin.v = mosquitto_malloc(len);
552
1.46k
    if(!prop->value.bin.v){
553
0
      mosquitto_FREE(prop);
554
0
      return MOSQ_ERR_NOMEM;
555
0
    }
556
557
1.46k
    memcpy(prop->value.bin.v, value, len);
558
1.46k
    prop->value.bin.len = len;
559
1.46k
  }
560
561
2.22k
  property__add(proplist, prop);
562
2.22k
  return MOSQ_ERR_SUCCESS;
563
2.22k
}
564
565
566
BROKER_EXPORT int mosquitto_property_add_string(mosquitto_property **proplist, int identifier, const char *value)
567
5.10k
{
568
5.10k
  mosquitto_property *prop;
569
5.10k
  size_t slen = 0;
570
571
5.10k
  if(!proplist){
572
0
    return MOSQ_ERR_INVAL;
573
0
  }
574
5.10k
  if(value){
575
5.10k
    slen = strlen(value);
576
5.10k
    if(mosquitto_validate_utf8(value, (int)slen)){
577
1.87k
      return MOSQ_ERR_MALFORMED_UTF8;
578
1.87k
    }
579
5.10k
  }
580
581
3.23k
  if(identifier != MQTT_PROP_CONTENT_TYPE
582
2.05k
      && identifier != MQTT_PROP_RESPONSE_TOPIC
583
1.52k
      && identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
584
1.33k
      && identifier != MQTT_PROP_AUTHENTICATION_METHOD
585
1.13k
      && identifier != MQTT_PROP_RESPONSE_INFORMATION
586
944
      && identifier != MQTT_PROP_SERVER_REFERENCE
587
750
      && identifier != MQTT_PROP_REASON_STRING){
588
589
555
    return MOSQ_ERR_INVAL;
590
555
  }
591
592
2.67k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
593
2.67k
  if(!prop){
594
0
    return MOSQ_ERR_NOMEM;
595
0
  }
596
597
2.67k
  prop->client_generated = true;
598
2.67k
  prop->identifier = identifier;
599
2.67k
  prop->property_type = MQTT_PROP_TYPE_STRING;
600
2.67k
  if(value && slen > 0){
601
669
    prop->value.s.v = mosquitto_strdup(value);
602
669
    if(!prop->value.s.v){
603
0
      mosquitto_FREE(prop);
604
0
      return MOSQ_ERR_NOMEM;
605
0
    }
606
669
    prop->value.s.len = (uint16_t)slen;
607
669
  }
608
609
2.67k
  property__add(proplist, prop);
610
2.67k
  return MOSQ_ERR_SUCCESS;
611
2.67k
}
612
613
614
BROKER_EXPORT int mosquitto_property_add_string_pair(mosquitto_property **proplist, int identifier, const char *name, const char *value)
615
1.90k
{
616
1.90k
  mosquitto_property *prop;
617
1.90k
  size_t slen_name = 0, slen_value = 0;
618
619
1.90k
  if(!proplist){
620
0
    return MOSQ_ERR_INVAL;
621
0
  }
622
1.90k
  if(identifier != MQTT_PROP_USER_PROPERTY){
623
602
    return MOSQ_ERR_INVAL;
624
602
  }
625
1.30k
  if(name){
626
1.30k
    slen_name = strlen(name);
627
1.30k
    if(mosquitto_validate_utf8(name, (int)slen_name)){
628
209
      return MOSQ_ERR_MALFORMED_UTF8;
629
209
    }
630
1.30k
  }
631
1.09k
  if(value){
632
1.09k
    if(mosquitto_validate_utf8(value, (int)slen_value)){
633
0
      return MOSQ_ERR_MALFORMED_UTF8;
634
0
    }
635
1.09k
  }
636
637
1.09k
  prop = mosquitto_calloc(1, sizeof(mosquitto_property));
638
1.09k
  if(!prop){
639
0
    return MOSQ_ERR_NOMEM;
640
0
  }
641
642
1.09k
  prop->client_generated = true;
643
1.09k
  prop->identifier = identifier;
644
1.09k
  prop->property_type = MQTT_PROP_TYPE_STRING_PAIR;
645
646
1.09k
  if(name){
647
1.09k
    prop->name.v = mosquitto_strdup(name);
648
1.09k
    if(!prop->name.v){
649
0
      mosquitto_FREE(prop);
650
0
      return MOSQ_ERR_NOMEM;
651
0
    }
652
1.09k
    prop->name.len = (uint16_t)strlen(name);
653
1.09k
  }
654
655
1.09k
  if(value){
656
1.09k
    prop->value.s.v = mosquitto_strdup(value);
657
1.09k
    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
1.09k
    prop->value.s.len = (uint16_t)strlen(value);
663
1.09k
  }
664
665
1.09k
  property__add(proplist, prop);
666
1.09k
  return MOSQ_ERR_SUCCESS;
667
1.09k
}
668
669
670
BROKER_EXPORT int mosquitto_property_check_all(int command, const mosquitto_property *properties)
671
12.4k
{
672
12.4k
  const mosquitto_property *p, *tail;
673
12.4k
  int rc;
674
675
12.4k
  p = properties;
676
677
34.4k
  while(p){
678
    /* Validity checks */
679
23.1k
    if(p->identifier == MQTT_PROP_REQUEST_PROBLEM_INFORMATION
680
23.0k
        || 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
3.38k
      if(p->value.i8 > 1){
689
114
        return MOSQ_ERR_PROTOCOL;
690
114
      }
691
19.7k
    }else if(p->identifier == MQTT_PROP_MAXIMUM_PACKET_SIZE){
692
419
      if(p->value.i32 == 0){
693
9
        return MOSQ_ERR_PROTOCOL;
694
9
      }
695
19.3k
    }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
1.91k
      if(mosquitto_pub_topic_check(p->value.s.v) != MOSQ_ERR_SUCCESS){
703
56
        return MOSQ_ERR_PROTOCOL;
704
56
      }
705
1.91k
    }
706
707
    /* Check for properties on incorrect commands */
708
22.9k
    rc = mosquitto_property_check_command(command, p->identifier);
709
22.9k
    if(rc){
710
1.02k
      return rc;
711
1.02k
    }
712
713
    /* Check for duplicates */
714
21.9k
    if(p->identifier != MQTT_PROP_USER_PROPERTY){
715
12.7k
      tail = p->next;
716
29.7k
      while(tail){
717
16.9k
        if(p->identifier == tail->identifier){
718
25
          return MOSQ_ERR_DUPLICATE_PROPERTY;
719
25
        }
720
16.9k
        tail = tail->next;
721
16.9k
      }
722
12.7k
    }
723
724
21.9k
    p = p->next;
725
21.9k
  }
726
727
11.2k
  return MOSQ_ERR_SUCCESS;
728
12.4k
}
729
730
731
static const mosquitto_property *property__get_property(const mosquitto_property *proplist, int identifier, bool skip_first)
732
1.09k
{
733
1.09k
  const mosquitto_property *p;
734
1.09k
  bool is_first = true;
735
736
1.09k
  p = proplist;
737
738
9.58k
  while(p){
739
8.86k
    if(p->identifier == identifier){
740
372
      if(!is_first || !skip_first){
741
372
        return p;
742
372
      }
743
0
      is_first = false;
744
0
    }
745
8.48k
    p = p->next;
746
8.48k
  }
747
726
  return NULL;
748
1.09k
}
749
750
751
BROKER_EXPORT int mosquitto_property_identifier(const mosquitto_property *property)
752
19.1k
{
753
19.1k
  if(property == NULL){
754
0
    return 0;
755
0
  }
756
757
19.1k
  return property->identifier;
758
19.1k
}
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.1k
{
773
29.1k
  if(proplist == NULL){
774
0
    return NULL;
775
0
  }
776
777
29.1k
  return proplist->next;
778
29.1k
}
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
258
{
783
258
  const mosquitto_property *p;
784
258
  if(!proplist){
785
88
    return NULL;
786
88
  }
787
788
170
  p = property__get_property(proplist, identifier, skip_first);
789
170
  if(!p){
790
135
    return NULL;
791
135
  }
792
35
  if(p->identifier != MQTT_PROP_PAYLOAD_FORMAT_INDICATOR
793
35
      && p->identifier != MQTT_PROP_REQUEST_PROBLEM_INFORMATION
794
35
      && p->identifier != MQTT_PROP_REQUEST_RESPONSE_INFORMATION
795
35
      && 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
35
  if(value){
804
35
    *value = p->value.i8;
805
35
  }
806
807
35
  return p;
808
35
}
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
387
{
813
387
  const mosquitto_property *p;
814
387
  if(!proplist){
815
132
    return NULL;
816
132
  }
817
818
255
  p = property__get_property(proplist, identifier, skip_first);
819
255
  if(!p){
820
170
    return NULL;
821
170
  }
822
85
  if(p->identifier != MQTT_PROP_SERVER_KEEP_ALIVE
823
66
      && 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
85
  if(value){
830
85
    *value = p->value.i16;
831
85
  }
832
833
85
  return p;
834
85
}
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
129
{
839
129
  const mosquitto_property *p;
840
129
  if(!proplist){
841
44
    return NULL;
842
44
  }
843
844
85
  p = property__get_property(proplist, identifier, skip_first);
845
85
  if(!p){
846
77
    return NULL;
847
77
  }
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
244
{
866
244
  const mosquitto_property *p;
867
244
  if(!proplist){
868
143
    return NULL;
869
143
  }
870
871
101
  p = property__get_property(proplist, identifier, skip_first);
872
101
  if(!p){
873
28
    return NULL;
874
28
  }
875
73
  if(p->identifier != MQTT_PROP_SUBSCRIPTION_IDENTIFIER){
876
0
    return NULL;
877
0
  }
878
879
73
  if(value){
880
73
    *value = p->value.varint;
881
73
  }
882
883
73
  return p;
884
73
}
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.07k
{
889
1.07k
  const mosquitto_property *p;
890
1.07k
  if(!proplist || (value && !len) || (!value && len)){
891
870
    return NULL;
892
870
  }
893
894
204
  if(value){
895
204
    *value = NULL;
896
204
  }
897
898
204
  p = property__get_property(proplist, identifier, skip_first);
899
204
  if(!p){
900
148
    return NULL;
901
148
  }
902
56
  if(p->identifier != MQTT_PROP_CORRELATION_DATA
903
56
      && p->identifier != MQTT_PROP_AUTHENTICATION_DATA){
904
905
0
    return NULL;
906
0
  }
907
908
56
  if(value){
909
56
    *len = p->value.bin.len;
910
56
    if(p->value.bin.len){
911
26
      *value = mosquitto_calloc(1, *len + 1U);
912
26
      if(!(*value)){
913
0
        return NULL;
914
0
      }
915
916
26
      memcpy(*value, p->value.bin.v, *len);
917
30
    }else{
918
30
      *value = NULL;
919
30
    }
920
56
  }
921
922
56
  return p;
923
56
}
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.15k
{
928
1.15k
  const mosquitto_property *p;
929
1.15k
  if(!proplist){
930
871
    return NULL;
931
871
  }
932
933
283
  p = property__get_property(proplist, identifier, skip_first);
934
283
  if(!p){
935
168
    return NULL;
936
168
  }
937
115
  if(p->identifier != MQTT_PROP_CONTENT_TYPE
938
115
      && p->identifier != MQTT_PROP_RESPONSE_TOPIC
939
115
      && p->identifier != MQTT_PROP_ASSIGNED_CLIENT_IDENTIFIER
940
115
      && 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
115
  if(value){
949
115
    if(p->value.s.len){
950
83
      *value = mosquitto_calloc(1, (size_t)p->value.s.len+1);
951
83
      if(!(*value)){
952
0
        return NULL;
953
0
      }
954
955
83
      memcpy(*value, p->value.s.v, p->value.s.len);
956
83
    }else{
957
32
      *value = NULL;
958
32
    }
959
115
  }
960
961
115
  return p;
962
115
}
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.93k
{
1047
2.93k
  mosquitto_property *pnew, *plast = NULL;
1048
1049
2.93k
  if(!src){
1050
2.39k
    return MOSQ_ERR_SUCCESS;
1051
2.39k
  }
1052
534
  if(!dest){
1053
0
    return MOSQ_ERR_INVAL;
1054
0
  }
1055
1056
534
  *dest = NULL;
1057
1058
10.9k
  while(src){
1059
10.4k
    pnew = mosquitto_calloc(1, sizeof(mosquitto_property));
1060
10.4k
    if(!pnew){
1061
0
      mosquitto_property_free_all(dest);
1062
0
      return MOSQ_ERR_NOMEM;
1063
0
    }
1064
10.4k
    if(plast){
1065
9.87k
      plast->next = pnew;
1066
9.87k
    }else{
1067
534
      *dest = pnew;
1068
534
    }
1069
10.4k
    plast = pnew;
1070
1071
10.4k
    pnew->client_generated = src->client_generated;
1072
10.4k
    pnew->identifier = src->identifier;
1073
10.4k
    pnew->property_type = src->property_type;
1074
10.4k
    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
1.00k
      case MQTT_PROP_TYPE_INT32:
1084
1.00k
        pnew->value.i32 = src->value.i32;
1085
1.00k
        break;
1086
1087
260
      case MQTT_PROP_TYPE_VARINT:
1088
260
        pnew->value.varint = src->value.varint;
1089
260
        break;
1090
1091
2.67k
      case MQTT_PROP_TYPE_STRING:
1092
2.67k
        pnew->value.s.len = src->value.s.len;
1093
2.67k
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char *)mosquitto_calloc(1, 1);
1094
2.67k
        if(!pnew->value.s.v){
1095
0
          mosquitto_property_free_all(dest);
1096
0
          return MOSQ_ERR_NOMEM;
1097
0
        }
1098
2.67k
        break;
1099
1100
2.67k
      case MQTT_PROP_TYPE_BINARY:
1101
2.22k
        pnew->value.bin.len = src->value.bin.len;
1102
2.22k
        if(src->value.bin.len){
1103
1.46k
          pnew->value.bin.v = mosquitto_malloc(pnew->value.bin.len);
1104
1.46k
          if(!pnew->value.bin.v){
1105
0
            mosquitto_property_free_all(dest);
1106
0
            return MOSQ_ERR_NOMEM;
1107
0
          }
1108
1.46k
          memcpy(pnew->value.bin.v, src->value.bin.v, pnew->value.bin.len);
1109
1.46k
        }
1110
2.22k
        break;
1111
1112
2.22k
      case MQTT_PROP_TYPE_STRING_PAIR:
1113
1.09k
        pnew->value.s.len = src->value.s.len;
1114
1.09k
        pnew->value.s.v = src->value.s.v ? mosquitto_strdup(src->value.s.v) : (char *)mosquitto_calloc(1, 1);
1115
1.09k
        if(!pnew->value.s.v){
1116
0
          mosquitto_property_free_all(dest);
1117
0
          return MOSQ_ERR_NOMEM;
1118
0
        }
1119
1120
1.09k
        pnew->name.len = src->name.len;
1121
1.09k
        pnew->name.v = src->name.v ? mosquitto_strdup(src->name.v) : (char *)mosquitto_calloc(1, 1);
1122
1.09k
        if(!pnew->name.v){
1123
0
          mosquitto_property_free_all(dest);
1124
0
          return MOSQ_ERR_NOMEM;
1125
0
        }
1126
1.09k
        break;
1127
1128
1.09k
      default:
1129
0
        mosquitto_property_free_all(dest);
1130
0
        return MOSQ_ERR_INVAL;
1131
10.4k
    }
1132
1133
10.4k
    src = mosquitto_property_next(src);
1134
10.4k
  }
1135
1136
534
  return MOSQ_ERR_SUCCESS;
1137
534
}
1138
1139
1140
uint8_t mosquitto_property_byte_value(const mosquitto_property *property)
1141
1.52k
{
1142
1.52k
  if(property && property->property_type == MQTT_PROP_TYPE_BYTE){
1143
1.52k
    return property->value.i8;
1144
1.52k
  }else{
1145
0
    return 0;
1146
0
  }
1147
1.52k
}
1148
1149
1150
uint16_t mosquitto_property_int16_value(const mosquitto_property *property)
1151
192
{
1152
192
  if(property && property->property_type == MQTT_PROP_TYPE_INT16){
1153
192
    return property->value.i16;
1154
192
  }else{
1155
0
    return 0;
1156
0
  }
1157
192
}
1158
1159
1160
uint32_t mosquitto_property_int32_value(const mosquitto_property *property)
1161
264
{
1162
264
  if(property && property->property_type == MQTT_PROP_TYPE_INT32){
1163
264
    return property->value.i32;
1164
264
  }else{
1165
0
    return 0;
1166
0
  }
1167
264
}
1168
1169
1170
uint32_t mosquitto_property_varint_value(const mosquitto_property *property)
1171
1.50k
{
1172
1.50k
  if(property && property->property_type == MQTT_PROP_TYPE_VARINT){
1173
1.50k
    return property->value.varint;
1174
1.50k
  }else{
1175
0
    return 0;
1176
0
  }
1177
1.50k
}
1178
1179
1180
const void *mosquitto_property_binary_value(const mosquitto_property *property)
1181
783
{
1182
783
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1183
783
    return property->value.bin.v;
1184
783
  }else{
1185
0
    return NULL;
1186
0
  }
1187
783
}
1188
1189
1190
uint16_t mosquitto_property_binary_value_length(const mosquitto_property *property)
1191
2.32k
{
1192
2.32k
  if(property && property->property_type == MQTT_PROP_TYPE_BINARY){
1193
2.32k
    return property->value.bin.len;
1194
2.32k
  }else{
1195
0
    return 0;
1196
0
  }
1197
2.32k
}
1198
1199
1200
const char *mosquitto_property_string_value(const mosquitto_property *property)
1201
1.04k
{
1202
1.04k
  if(property && (property->property_type == MQTT_PROP_TYPE_STRING || property->property_type == MQTT_PROP_TYPE_STRING_PAIR)){
1203
1.04k
    return property->value.s.v;
1204
1.04k
  }else{
1205
0
    return NULL;
1206
0
  }
1207
1.04k
}
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
210
{
1222
210
  if(property && property->property_type == MQTT_PROP_TYPE_STRING_PAIR){
1223
210
    return property->name.v;
1224
210
  }else{
1225
0
    return NULL;
1226
0
  }
1227
210
}
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.41k
{
1244
1.41k
  unsigned int proplen, varbytes;
1245
1246
1.41k
  proplen = mosquitto_property_get_length_all(props);
1247
1.41k
  varbytes = mosquitto_varint_bytes(proplen);
1248
1.41k
  return proplen + varbytes;
1249
1.41k
}
1250
1251