// Check the tree to see if there is a path that is earlier/higher in the // filesystem than the input path; if there is, and it is recursive, // return true to indicate that there is no need to track this new path // due to the already scheduled higher level path. bool PendingCollectionBase::isObsoletedByContainingDir(const w_string& path) { auto leaf = tree_.longestMatch((const uint8_t*)path.data(), path.size()); if (!leaf) { return false; } auto p = leaf->value; if ((p->flags & W_PENDING_RECURSIVE) && is_path_prefix( path.data(), path.size(), (const char*)leaf->key.data(), leaf->key.size())) { if (watchman::CookieSync::isPossiblyACookie(path)) { return false; } // Yes: the pre-existing entry higher up in the tree obsoletes this // one that we would add now. w_log( W_LOG_DBG, "is_obsoleted: SKIP %.*s is obsoleted by %.*s\n", int(path.size()), path.data(), int(p->path.size()), p->path.data()); return true; } return false; }
void add_cookies(unsigned char **s, int *l, unsigned char *url) { int nc = 0; struct c_domain *cd; struct cookie *c, *d; unsigned char *server = get_host_name(url); unsigned char *data = get_url_data(url); if (data > url) data--; foreach (cd, c_domains) if (is_in_domain(cd->domain, server)) goto ok; mem_free(server); return; ok: foreachback (c, all_cookies) if (is_in_domain(c->domain, server)) if (is_path_prefix(c->path, data)) { if (cookie_expired(c)) { d = c; c = c->prev; del_from_list(d); free_cookie(d); mem_free(d); continue; } if (c->secure && casecmp(url, cast_uchar "https://", 8)) continue; if (!nc) add_to_str(s, l, cast_uchar "Cookie: "), nc = 1; else add_to_str(s, l, cast_uchar "; "); add_to_str(s, l, c->name); if (c->value) { add_to_str(s, l, cast_uchar "="); add_to_str(s, l, c->value); } } if (nc) add_to_str(s, l, cast_uchar "\r\n"); mem_free(server); }
// This is the iterator callback we use to prune out obsoleted leaves. // We need to compare the prefix to make sure that we don't delete // a sibling node by mistake (see commentary on the is_path_prefix // function for more on that). int PendingCollectionBase::iterContext::operator()( const w_string& key, std::shared_ptr<watchman_pending_fs>& p) { if (!p) { // It was removed; update the tree to reflect this coll.tree_.erase(key); // Stop iteration: we deleted something and invalidated the iterators. return 1; } if ((p->flags & W_PENDING_CRAWL_ONLY) == 0 && key.size() > root.size() && is_path_prefix( (const char*)key.data(), key.size(), root.data(), root.size()) && !watchman::CookieSync::isPossiblyACookie(p->path)) { w_log( W_LOG_DBG, "delete_kids: removing (%d) %.*s from pending because it is " "obsoleted by (%d) %.*s\n", int(p->path.size()), int(p->path.size()), p->path.data(), int(root.size()), int(root.size()), root.data()); // Unlink the child from the pending index. coll.unlinkItem(p); // Remove it from the art tree. coll.tree_.erase(key); // Stop iteration because we just invalidated the iterator state // by modifying the tree mid-iteration. return 1; } return 0; }