/* * Check if all of the elements of list1 are in list2 * It compares GLists of X using the comparison function */ static gboolean compare_lists (GList *list1, GList *list2, gboolean (*compare_params) (const gpointer p1, const gpointer p2)) { GList *item1; for (item1 = g_list_first (list1); item1; item1 = g_list_next (item1)) { FsCodecParameter *param1 = item1->data; GList *item2 = NULL; for (item2 = g_list_first (list2); item2; item2 = g_list_next (item2)) { FsCodecParameter *param2 = item2->data; if (compare_params (param1, param2)) break; } if (!item2) return FALSE; } return TRUE; }
/* * Described in header */ bool signature_params_comply(signature_params_t *c, signature_params_t *s) { /* the salt is variable, so it does not necessarily have to be the same */ return compare_params(c, s, FALSE); }
static const char * sort_querystring(struct ws *ws, const char *uri) { if (uri == NULL) { return NULL; } char *query_string = strchr(uri, '?'); if (query_string == NULL) { return uri; } if (query_string[1] == '\0') { return truncate_querystring(ws, uri, query_string); } /* reserve some memory */ char *snapshot = WS_Snapshot(ws); char *sorted_uri = WS_Alloc(ws, strlen(uri) + 1); WS_Assert(ws); if (sorted_uri == NULL) { WS_Reset(ws, snapshot); return uri; } unsigned available = WS_Reserve(ws, 0); struct query_param *params = (struct query_param*) ws->f; struct query_param *end = params + available; /* initialize the params array */ int head = 10; if (¶ms[head + 1] > end) { head = 0; } if (¶ms[head + 1] > end) { WS_Release(ws, 0); WS_Reset(ws, snapshot); return uri; } int tail = head; int last_param = head; /* search and sort params */ bool sorted = true; char *c = query_string + 1; params[head].value = c; for (; *c != '\0' && ¶ms[tail+1] < end; c++) { if (*c != '&') { continue; } const char *current_param = c+1; params[last_param].length = c - params[last_param].value; if (head > 0 && compare_params(params[head].value, current_param) > -1) { sorted = false; params[--head].value = current_param; last_param = head; continue; } if (compare_params(params[tail].value, current_param) < 1) { params[++tail].value = current_param; last_param = tail; continue; } sorted = false; int i = tail++; params[tail] = params[i]; int previous = i-1; while (i > head && compare_params(params[previous].value, current_param) > -1) { params[i--] = params[previous--]; } params[i].value = current_param; last_param = i; } if (sorted == true || ¶ms[tail+1] >= end || tail - head < 1) { WS_Release(ws, 0); WS_Reset(ws, snapshot); return uri; } params[last_param].length = c - params[last_param].value; /* copy the url parts */ char *position = mempcpy(sorted_uri, uri, query_string - uri + 1); int count = tail-head; for (;count > 0; count--, ++head) { if (params[head].length > 0) { position = mempcpy(position, params[head].value, params[head].length); *position++ = '&'; } } if (params[head].length > 0) { position = mempcpy(position, params[head].value, params[head].length); } else { position--; } *position = '\0'; WS_Release(ws, 0); return sorted_uri; }
/* * Described in header */ bool signature_params_equal(signature_params_t *a, signature_params_t *b) { return compare_params(a, b, TRUE); }