Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 5 additions & 11 deletions packages/hydrooj/src/handler/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -438,21 +438,15 @@ export const DomainApi = {
),
groups: Query(
Schema.object({
search: Schema.string(),
names: Schema.array(Schema.string()),
domainId: Schema.string().required(),
uid: Schema.number().step(1),
names: Schema.array(Schema.string()),
search: Schema.string(),
limit: Schema.number().step(1).max(100),
}),
async (ctx, args) => {
if (!ctx.user.hasPerm(PERM.PERM_VIEW) && !ctx.user.hasPriv(PRIV.PRIV_VIEW_ALL_DOMAIN)) throw new PermissionError(PERM.PERM_VIEW);
const groups = await user.listGroup(args.domainId);
if (args.names?.length) {
return groups.filter((g) => args.names.includes(g.name));
}
if (args.search) {
const searchLower = args.search.toLowerCase();
return groups.filter((g) => g.name.toLowerCase().includes(searchLower));
}
return groups;
return user.listGroup(args.domainId, args.uid, args.names, args.search, args.search ? (args.limit ?? 10) : undefined);
},
),
'domain.group': Mutation(
Expand Down
10 changes: 8 additions & 2 deletions packages/hydrooj/src/model/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -479,8 +479,14 @@ class UserModel {
]);
}

static async listGroup(domainId: string, uid?: number) {
const groups = await collGroup.find(typeof uid === 'number' ? { domainId, uids: uid } : { domainId }).toArray();
static async listGroup(domainId: string, uid?: number, names?: string[], search?: string, limit?: number) {
const filter: Filter<GDoc> = { domainId };
if (typeof uid === 'number') filter.uids = uid;
if (names?.length) filter.name = { $in: names };
if (search) filter.name = { $regex: escapeRegExp(search), $options: 'i' };
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
let cursor = collGroup.find(filter);
if (limit) cursor = cursor.limit(limit);
Comment on lines +495 to +496

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Treat 0 as invalid instead of "no limit".

This truthy check makes limit = 0 skip .limit() entirely, so a caller can turn the new search path into an unbounded query. Reject or clamp non-positive values before building the cursor.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/hydrooj/src/model/user.ts` around lines 487 - 488, The current check
uses "if (limit)" so limit = 0 is treated as no limit; update the code that
builds the Mongo cursor (the collGroup.find(filter) and subsequent .limit()
call) to treat non-positive values as invalid by checking if (typeof limit ===
'number' && limit > 0) before calling cursor.limit(limit), or clamp
negative/zero to a safe minimum (e.g., 1) or explicitly throw/bail; ensure the
change references the same variables/functions (collGroup.find, cursor, limit,
.limit()) so callers cannot supply 0 to create an unbounded query.

const groups = await cursor.toArray();
if (uid) {
groups.push({
_id: new ObjectId(), domainId, uids: [uid], name: uid.toString(),
Expand Down
Loading