Skip to content

Commit a3c2a19

Browse files
committed
Refactor Lock-Token parsing into reusable helper and remove duplicated logic
1 parent 2a003b5 commit a3c2a19

4 files changed

Lines changed: 54 additions & 44 deletions

File tree

modules/dav/main/mod_dav.c

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3587,9 +3587,6 @@ static int dav_method_unlock(request_rec *r)
35873587
dav_resource *resource;
35883588
const dav_hooks_locks *locks_hooks;
35893589
int result;
3590-
apr_size_t len;
3591-
int has_open;
3592-
int has_close;
35933590
const char *const_locktoken_txt;
35943591
char *locktoken_txt;
35953592
dav_locktoken *locktoken = NULL;
@@ -3609,25 +3606,9 @@ static int dav_method_unlock(request_rec *r)
36093606
return HTTP_BAD_REQUEST;
36103607
}
36113608

3612-
locktoken_txt = apr_pstrdup(r->pool, const_locktoken_txt);
3613-
len = strlen(locktoken_txt);
3614-
3615-
has_open = (len > 0 && locktoken_txt[0] == '<');
3616-
has_close = (len > 0 && locktoken_txt[len - 1] == '>');
3617-
3618-
if (has_open && has_close && len >= 2) {
3619-
locktoken_txt[len - 1] = '\0';
3620-
locktoken_txt++;
3621-
3622-
if (*locktoken_txt == '\0') {
3623-
/* ### should provide more specifics... */
3624-
return HTTP_BAD_REQUEST;
3625-
}
3626-
}
3627-
else {
3628-
/* ### should provide more specifics... */
3629-
return HTTP_BAD_REQUEST;
3630-
}
3609+
err = dav_parse_locktoken(r->pool, const_locktoken_txt, &locktoken_txt);
3610+
if (err != NULL)
3611+
return err->status;
36313612

36323613
if ((err = (*locks_hooks->parse_locktoken)(r->pool, locktoken_txt,
36333614
&locktoken)) != NULL) {

modules/dav/main/mod_dav.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,9 @@ struct dav_hooks_propdb
13311331

13321332
DAV_DECLARE(time_t) dav_get_timeout(request_rec *r);
13331333
DAV_DECLARE(time_t) dav_get_timeout_string(request_rec *r, const char *s);
1334+
DAV_DECLARE(dav_error *) dav_parse_locktoken(apr_pool_t *p,
1335+
const char *input,
1336+
char **output);
13341337

13351338
/*
13361339
** Opaque, provider-specific information for a lock database.
@@ -2756,5 +2759,4 @@ DAV_DECLARE(const dav_resource_type_provider *) dav_get_resource_type_providers(
27562759
#endif
27572760

27582761
#endif /* _MOD_DAV_H_ */
2759-
/** @} */
2760-
2762+
/** @} */

modules/dav/main/ms_wdv.c

Lines changed: 5 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -205,27 +205,13 @@ static dav_error *mswdv_combined_lock(request_rec *r)
205205
* section 4.5 suggests using Lock-Token without brakets.
206206
*/
207207
if (lock_token_hdr) {
208-
apr_size_t len = strlen(lock_token_hdr);
209-
int has_open = (len > 0 && lock_token_hdr[0] == '<');
210-
int has_close = (len > 0 && lock_token_hdr[len - 1] == '>');
208+
char *parsed_locktoken;
211209

212-
/*
213-
* Defensive parsing: never read len - 1 or compute len - 2 unless
214-
* length is known to be valid, and reject malformed one-sided
215-
* bracket usage before token parsing.
216-
*/
217-
if (has_open && has_close && len >= 2) {
218-
lock_token_hdr = apr_pstrndup(r->pool, lock_token_hdr + 1, len - 2);
219-
}
220-
else if (has_open || has_close) {
221-
failmsg = "Malformed Lock-Token header.";
222-
goto done;
223-
}
210+
err = dav_parse_locktoken(r->pool, lock_token_hdr, &parsed_locktoken);
211+
if (err != NULL)
212+
goto out;
224213

225-
if (*lock_token_hdr == '\0') {
226-
failmsg = "Malformed Lock-Token header.";
227-
goto done;
228-
}
214+
lock_token_hdr = parsed_locktoken;
229215
}
230216

231217
if (lock_timeout_hdr) {

modules/dav/main/util.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -590,6 +590,47 @@ DAV_DECLARE(time_t) dav_get_timeout_string(request_rec *r,
590590
return DAV_TIMEOUT_INFINITE;
591591
}
592592

593+
DAV_DECLARE(dav_error *) dav_parse_locktoken(apr_pool_t *p,
594+
const char *input,
595+
char **output)
596+
{
597+
char *token;
598+
apr_size_t len;
599+
int has_open;
600+
int has_close;
601+
602+
if (output == NULL) {
603+
return dav_new_error(p, HTTP_INTERNAL_SERVER_ERROR, 0, 0,
604+
"DAV lock token parser called with NULL output pointer.");
605+
}
606+
*output = NULL;
607+
608+
if (input == NULL) {
609+
return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
610+
"No Lock-Token specified in header.");
611+
}
612+
613+
len = strlen(input);
614+
615+
has_open = (len > 0 && input[0] == '<');
616+
has_close = (len > 0 && input[len - 1] == '>');
617+
618+
if (len < 2 || !has_open || !has_close) {
619+
return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
620+
"Malformed Lock-Token header.");
621+
}
622+
623+
token = apr_pstrndup(p, input + 1, len - 2);
624+
625+
if (*token == '\0') {
626+
return dav_new_error(p, HTTP_BAD_REQUEST, 0, 0,
627+
"Malformed Lock-Token header.");
628+
}
629+
630+
*output = token;
631+
return NULL;
632+
}
633+
593634
/* ---------------------------------------------------------------
594635
**
595636
** If Header processing
@@ -2228,4 +2269,4 @@ DAV_DECLARE(dav_error *) dav_auto_checkin(
22282269
}
22292270

22302271
return NULL;
2231-
}
2272+
}

0 commit comments

Comments
 (0)