Fossil SCM
Refactored [dd490d17be] into a separate routine and applied it to the POST parsing handler to fix problem reported at [https://fossil-scm.org/forum/forumpost/f3e11f5629].
Commit
23e138e808ff34066a91ce1b454b928bb2de898795770a72b001e1a0f84c6a6b
Parent
dd490d17bec777c…
2 files changed
+1
-2
+37
-20
+1
-2
| --- src/cgi.c | ||
| +++ src/cgi.c | ||
| @@ -1101,12 +1101,11 @@ | ||
| 1101 | 1101 | for(j=i; zRequestUri[j] && zRequestUri[j]!='?'; j++){} |
| 1102 | 1102 | zPathInfo = mprintf("%.*s", j-i, zRequestUri+i); |
| 1103 | 1103 | cgi_set_parameter("PATH_INFO", zPathInfo); |
| 1104 | 1104 | } |
| 1105 | 1105 | #ifdef FOSSIL_ENABLE_JSON |
| 1106 | - if(strncmp("/json",zPathInfo,5)==0 | |
| 1107 | - && (zPathInfo[5]==0 || zPathInfo[5]=='/')){ | |
| 1106 | + if(json_request_is_json_api(zPathInfo)){ | |
| 1108 | 1107 | /* We need to change some following behaviour depending on whether |
| 1109 | 1108 | ** we are operating in JSON mode or not. We cannot, however, be |
| 1110 | 1109 | ** certain whether we should/need to be in JSON mode until the |
| 1111 | 1110 | ** PATH_INFO is set up. |
| 1112 | 1111 | */ |
| 1113 | 1112 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1101,12 +1101,11 @@ | |
| 1101 | for(j=i; zRequestUri[j] && zRequestUri[j]!='?'; j++){} |
| 1102 | zPathInfo = mprintf("%.*s", j-i, zRequestUri+i); |
| 1103 | cgi_set_parameter("PATH_INFO", zPathInfo); |
| 1104 | } |
| 1105 | #ifdef FOSSIL_ENABLE_JSON |
| 1106 | if(strncmp("/json",zPathInfo,5)==0 |
| 1107 | && (zPathInfo[5]==0 || zPathInfo[5]=='/')){ |
| 1108 | /* We need to change some following behaviour depending on whether |
| 1109 | ** we are operating in JSON mode or not. We cannot, however, be |
| 1110 | ** certain whether we should/need to be in JSON mode until the |
| 1111 | ** PATH_INFO is set up. |
| 1112 | */ |
| 1113 |
| --- src/cgi.c | |
| +++ src/cgi.c | |
| @@ -1101,12 +1101,11 @@ | |
| 1101 | for(j=i; zRequestUri[j] && zRequestUri[j]!='?'; j++){} |
| 1102 | zPathInfo = mprintf("%.*s", j-i, zRequestUri+i); |
| 1103 | cgi_set_parameter("PATH_INFO", zPathInfo); |
| 1104 | } |
| 1105 | #ifdef FOSSIL_ENABLE_JSON |
| 1106 | if(json_request_is_json_api(zPathInfo)){ |
| 1107 | /* We need to change some following behaviour depending on whether |
| 1108 | ** we are operating in JSON mode or not. We cannot, however, be |
| 1109 | ** certain whether we should/need to be in JSON mode until the |
| 1110 | ** PATH_INFO is set up. |
| 1111 | */ |
| 1112 |
+37
-20
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -1527,10 +1527,45 @@ | ||
| 1527 | 1527 | return 1; |
| 1528 | 1528 | } |
| 1529 | 1529 | return 0; |
| 1530 | 1530 | } |
| 1531 | 1531 | |
| 1532 | +#ifdef FOSSIL_ENABLE_JSON | |
| 1533 | +/* | |
| 1534 | +** Given the current request path string, this function returns true | |
| 1535 | +** if it refers to a JSON API path. i.e. if (1) it starts with /json | |
| 1536 | +** or (2) g.zCmdName is "server" and the path starts with | |
| 1537 | +** /somereponame/json. Specifically, it returns 1 in the former case | |
| 1538 | +** and 2 for the latter. | |
| 1539 | +*/ | |
| 1540 | +int json_request_is_json_api(const char * zPathInfo){ | |
| 1541 | + int rc = 0; | |
| 1542 | + if(zPathInfo==0){ | |
| 1543 | + rc = 0; | |
| 1544 | + }else if(0==strncmp("/json",zPathInfo,5) | |
| 1545 | + && (zPathInfo[5]==0 || zPathInfo[5]=='/')){ | |
| 1546 | + rc = 1; | |
| 1547 | + }else if(g.zCmdName!=0 && 0==strcmp("server",g.zCmdName)){ | |
| 1548 | + /* When running in server "directory" mode, zPathInfo is | |
| 1549 | + ** prefixed with the repository's name, so in order to determine | |
| 1550 | + ** whether or not we're really running in json mode we have to | |
| 1551 | + ** try a bit harder. Problem reported here: | |
| 1552 | + ** https://fossil-scm.org/forum/forumpost/e4953666d6 | |
| 1553 | + */ | |
| 1554 | + ReCompiled * pReg = 0; | |
| 1555 | + const char * zErr = re_compile(&pReg, "^/[^/]+/json(/.*)?", 0); | |
| 1556 | + assert(zErr==0 && "Regex compilation failed?"); | |
| 1557 | + if(zErr==0 && | |
| 1558 | + re_match(pReg, (const unsigned char *)zPathInfo, -1)){ | |
| 1559 | + rc = 2; | |
| 1560 | + } | |
| 1561 | + re_free(pReg); | |
| 1562 | + } | |
| 1563 | + return rc; | |
| 1564 | +} | |
| 1565 | +#endif | |
| 1566 | + | |
| 1532 | 1567 | /* |
| 1533 | 1568 | ** Preconditions: |
| 1534 | 1569 | ** |
| 1535 | 1570 | ** * Environment variables are set up according to the CGI standard. |
| 1536 | 1571 | ** |
| @@ -1579,30 +1614,12 @@ | ||
| 1579 | 1614 | ** process JSON-mode POST data if we're actually in a /json |
| 1580 | 1615 | ** page). This is normally set up before this routine is called, but |
| 1581 | 1616 | ** it looks like the ssh_request_loop() approach to dispatching |
| 1582 | 1617 | ** might bypass that. |
| 1583 | 1618 | */ |
| 1584 | - if( g.json.isJsonMode==0 && zPathInfo!=0 ){ | |
| 1585 | - if(0==strncmp("/json",zPathInfo,5) | |
| 1586 | - && (zPathInfo[5]==0 || zPathInfo[5]=='/')){ | |
| 1587 | - g.json.isJsonMode = 1; | |
| 1588 | - }else if(g.zCmdName!=0 && 0==strcmp("server",g.zCmdName)){ | |
| 1589 | - /* When running in server "directory" mode, zPathInfo is | |
| 1590 | - ** prefixed with the repository's name, so in order to determine | |
| 1591 | - ** whether or not we're really running in json mode we have to | |
| 1592 | - ** try a bit harder. Problem reported here: | |
| 1593 | - ** https://fossil-scm.org/forum/forumpost/e4953666d6 | |
| 1594 | - */ | |
| 1595 | - ReCompiled * pReg = 0; | |
| 1596 | - const char * zErr = re_compile(&pReg, "^/[^/]+/json(/.*)?", 0); | |
| 1597 | - assert(zErr==0 && "Regex compilation failed?"); | |
| 1598 | - if(zErr==0 && | |
| 1599 | - re_match(pReg, (const unsigned char *)zPathInfo, -1)){ | |
| 1600 | - g.json.isJsonMode = 1; | |
| 1601 | - } | |
| 1602 | - re_free(pReg); | |
| 1603 | - } | |
| 1619 | + if( g.json.isJsonMode==0 && json_request_is_json_api(zPathInfo) ){ | |
| 1620 | + g.json.isJsonMode = 1; | |
| 1604 | 1621 | } |
| 1605 | 1622 | #endif |
| 1606 | 1623 | /* If the repository has not been opened already, then find the |
| 1607 | 1624 | ** repository based on the first element of PATH_INFO and open it. |
| 1608 | 1625 | */ |
| 1609 | 1626 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1527,10 +1527,45 @@ | |
| 1527 | return 1; |
| 1528 | } |
| 1529 | return 0; |
| 1530 | } |
| 1531 | |
| 1532 | /* |
| 1533 | ** Preconditions: |
| 1534 | ** |
| 1535 | ** * Environment variables are set up according to the CGI standard. |
| 1536 | ** |
| @@ -1579,30 +1614,12 @@ | |
| 1579 | ** process JSON-mode POST data if we're actually in a /json |
| 1580 | ** page). This is normally set up before this routine is called, but |
| 1581 | ** it looks like the ssh_request_loop() approach to dispatching |
| 1582 | ** might bypass that. |
| 1583 | */ |
| 1584 | if( g.json.isJsonMode==0 && zPathInfo!=0 ){ |
| 1585 | if(0==strncmp("/json",zPathInfo,5) |
| 1586 | && (zPathInfo[5]==0 || zPathInfo[5]=='/')){ |
| 1587 | g.json.isJsonMode = 1; |
| 1588 | }else if(g.zCmdName!=0 && 0==strcmp("server",g.zCmdName)){ |
| 1589 | /* When running in server "directory" mode, zPathInfo is |
| 1590 | ** prefixed with the repository's name, so in order to determine |
| 1591 | ** whether or not we're really running in json mode we have to |
| 1592 | ** try a bit harder. Problem reported here: |
| 1593 | ** https://fossil-scm.org/forum/forumpost/e4953666d6 |
| 1594 | */ |
| 1595 | ReCompiled * pReg = 0; |
| 1596 | const char * zErr = re_compile(&pReg, "^/[^/]+/json(/.*)?", 0); |
| 1597 | assert(zErr==0 && "Regex compilation failed?"); |
| 1598 | if(zErr==0 && |
| 1599 | re_match(pReg, (const unsigned char *)zPathInfo, -1)){ |
| 1600 | g.json.isJsonMode = 1; |
| 1601 | } |
| 1602 | re_free(pReg); |
| 1603 | } |
| 1604 | } |
| 1605 | #endif |
| 1606 | /* If the repository has not been opened already, then find the |
| 1607 | ** repository based on the first element of PATH_INFO and open it. |
| 1608 | */ |
| 1609 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -1527,10 +1527,45 @@ | |
| 1527 | return 1; |
| 1528 | } |
| 1529 | return 0; |
| 1530 | } |
| 1531 | |
| 1532 | #ifdef FOSSIL_ENABLE_JSON |
| 1533 | /* |
| 1534 | ** Given the current request path string, this function returns true |
| 1535 | ** if it refers to a JSON API path. i.e. if (1) it starts with /json |
| 1536 | ** or (2) g.zCmdName is "server" and the path starts with |
| 1537 | ** /somereponame/json. Specifically, it returns 1 in the former case |
| 1538 | ** and 2 for the latter. |
| 1539 | */ |
| 1540 | int json_request_is_json_api(const char * zPathInfo){ |
| 1541 | int rc = 0; |
| 1542 | if(zPathInfo==0){ |
| 1543 | rc = 0; |
| 1544 | }else if(0==strncmp("/json",zPathInfo,5) |
| 1545 | && (zPathInfo[5]==0 || zPathInfo[5]=='/')){ |
| 1546 | rc = 1; |
| 1547 | }else if(g.zCmdName!=0 && 0==strcmp("server",g.zCmdName)){ |
| 1548 | /* When running in server "directory" mode, zPathInfo is |
| 1549 | ** prefixed with the repository's name, so in order to determine |
| 1550 | ** whether or not we're really running in json mode we have to |
| 1551 | ** try a bit harder. Problem reported here: |
| 1552 | ** https://fossil-scm.org/forum/forumpost/e4953666d6 |
| 1553 | */ |
| 1554 | ReCompiled * pReg = 0; |
| 1555 | const char * zErr = re_compile(&pReg, "^/[^/]+/json(/.*)?", 0); |
| 1556 | assert(zErr==0 && "Regex compilation failed?"); |
| 1557 | if(zErr==0 && |
| 1558 | re_match(pReg, (const unsigned char *)zPathInfo, -1)){ |
| 1559 | rc = 2; |
| 1560 | } |
| 1561 | re_free(pReg); |
| 1562 | } |
| 1563 | return rc; |
| 1564 | } |
| 1565 | #endif |
| 1566 | |
| 1567 | /* |
| 1568 | ** Preconditions: |
| 1569 | ** |
| 1570 | ** * Environment variables are set up according to the CGI standard. |
| 1571 | ** |
| @@ -1579,30 +1614,12 @@ | |
| 1614 | ** process JSON-mode POST data if we're actually in a /json |
| 1615 | ** page). This is normally set up before this routine is called, but |
| 1616 | ** it looks like the ssh_request_loop() approach to dispatching |
| 1617 | ** might bypass that. |
| 1618 | */ |
| 1619 | if( g.json.isJsonMode==0 && json_request_is_json_api(zPathInfo) ){ |
| 1620 | g.json.isJsonMode = 1; |
| 1621 | } |
| 1622 | #endif |
| 1623 | /* If the repository has not been opened already, then find the |
| 1624 | ** repository based on the first element of PATH_INFO and open it. |
| 1625 | */ |
| 1626 |