--- /dev/null
+From db3235953baa56d2fb0e276ca510fefca751643f Mon Sep 17 00:00:00 2001
+From: Nanang Izzuddin <nanang@teluu.com>
+Date: Mon, 21 Feb 2022 06:24:52 +0700
+Subject: [PATCH] Merge pull request from GHSA-ffff-m5fm-qm62
+
+* Update pjsip_ua_unregister_dlg():
+- update the hash key if the dialog being unregistered is used as hash key.
+- add an assertion check to make sure that the dlg_set to be removed is valid (can be found in the hash table).
+
+* Change hash key string comparison method.
+---
+ pjsip/src/pjsip/sip_ua_layer.c | 48 +++++++++++++++++++++++++++++-----
+ 1 file changed, 42 insertions(+), 6 deletions(-)
+
+--- a/pjsip/src/pjsip/sip_ua_layer.c
++++ b/pjsip/src/pjsip/sip_ua_layer.c
+@@ -65,6 +65,9 @@ struct dlg_set
+ /* This is the buffer to store this entry in the hash table. */
+ pj_hash_entry_buf ht_entry;
+
++ /* Entry key in the hash table */
++ pj_str_t ht_key;
++
+ /* List of dialog in this dialog set. */
+ struct dlg_set_head dlg_list;
+ };
+@@ -321,6 +324,7 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
+ * Create the dialog set and add this dialog to it.
+ */
+ dlg_set = alloc_dlgset_node();
++ dlg_set->ht_key = dlg->local.info->tag;
+ pj_list_init(&dlg_set->dlg_list);
+ pj_list_push_back(&dlg_set->dlg_list, dlg);
+
+@@ -328,8 +332,8 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
+
+ /* Register the dialog set in the hash table. */
+ pj_hash_set_np_lower(mod_ua.dlg_table,
+- dlg->local.info->tag.ptr,
+- (unsigned)dlg->local.info->tag.slen,
++ dlg_set->ht_key.ptr,
++ (unsigned)dlg_set->ht_key.slen,
+ dlg->local.tag_hval, dlg_set->ht_entry,
+ dlg_set);
+ }
+@@ -339,14 +343,15 @@ PJ_DEF(pj_status_t) pjsip_ua_register_dl
+ struct dlg_set *dlg_set;
+
+ dlg_set = alloc_dlgset_node();
++ dlg_set->ht_key = dlg->local.info->tag;
+ pj_list_init(&dlg_set->dlg_list);
+ pj_list_push_back(&dlg_set->dlg_list, dlg);
+
+ dlg->dlg_set = dlg_set;
+
+ pj_hash_set_np_lower(mod_ua.dlg_table,
+- dlg->local.info->tag.ptr,
+- (unsigned)dlg->local.info->tag.slen,
++ dlg_set->ht_key.ptr,
++ (unsigned)dlg_set->ht_key.slen,
+ dlg->local.tag_hval, dlg_set->ht_entry, dlg_set);
+ }
+
+@@ -391,12 +396,43 @@ PJ_DEF(pj_status_t) pjsip_ua_unregister_
+
+ /* If dialog list is empty, remove the dialog set from the hash table. */
+ if (pj_list_empty(&dlg_set->dlg_list)) {
+- pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg->local.info->tag.ptr,
+- (unsigned)dlg->local.info->tag.slen,
++
++ /* Verify that the dialog set is valid */
++ pj_assert(pj_hash_get_lower(mod_ua.dlg_table, dlg_set->ht_key.ptr,
++ (unsigned)dlg_set->ht_key.slen,
++ &dlg->local.tag_hval) == dlg_set);
++
++ pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
++ (unsigned)dlg_set->ht_key.slen,
+ dlg->local.tag_hval, NULL);
+
+ /* Return dlg_set to free nodes. */
+ pj_list_push_back(&mod_ua.free_dlgset_nodes, dlg_set);
++ } else {
++ /* If the just unregistered dialog is being used as hash key,
++ * reset the dlg_set entry with a new key (i.e: from the first dialog
++ * in dlg_set).
++ */
++ if (dlg_set->ht_key.ptr == dlg->local.info->tag.ptr &&
++ dlg_set->ht_key.slen == dlg->local.info->tag.slen)
++ {
++ pjsip_dialog* key_dlg = dlg_set->dlg_list.next;
++
++ /* Verify that the old & new keys share the hash value */
++ pj_assert(key_dlg->local.tag_hval == dlg->local.tag_hval);
++
++ pj_hash_set_lower(NULL, mod_ua.dlg_table, dlg_set->ht_key.ptr,
++ (unsigned)dlg_set->ht_key.slen,
++ dlg->local.tag_hval, NULL);
++
++ dlg_set->ht_key = key_dlg->local.info->tag;
++
++ pj_hash_set_np_lower(mod_ua.dlg_table,
++ dlg_set->ht_key.ptr,
++ (unsigned)dlg_set->ht_key.slen,
++ key_dlg->local.tag_hval, dlg_set->ht_entry,
++ dlg_set);
++ }
+ }
+
+ /* Unlock user agent. */
--- /dev/null
+From 077b465c33f0aec05a49cd2ca456f9a1b112e896 Mon Sep 17 00:00:00 2001
+From: sauwming <ming@teluu.com>
+Date: Wed, 26 Jan 2022 13:28:57 +0800
+Subject: [PATCH] Merge pull request from GHSA-7fw8-54cv-r7pm
+
+---
+ pjlib-util/src/pjlib-util/scanner.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+--- a/pjlib-util/src/pjlib-util/scanner.c
++++ b/pjlib-util/src/pjlib-util/scanner.c
+@@ -444,16 +444,21 @@ PJ_DEF(void) pj_scan_get_n( pj_scanner *
+
+ PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )
+ {
+- int chr = *scanner->curptr;
++ register char *s = scanner->curptr;
++ int chr;
+
+- if (!chr) {
++ if (s >= scanner->end || !*s) {
+ pj_scan_syntax_err(scanner);
+ return 0;
+ }
+
+- ++scanner->curptr;
++ chr = *s;
+
+- if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
++ ++s;
++ scanner->curptr = s;
++ if (PJ_SCAN_CHECK_EOF(s) && PJ_SCAN_IS_PROBABLY_SPACE(*s) &&
++ scanner->skip_ws)
++ {
+ pj_scan_skip_whitespace(scanner);
+ }
+ return chr;