Fossil SCM
Validate the email address in the subscription editing form.
Commit
32a8d1102527724a43977c05f18d105f68d699cd1e02f5f32952826c58db2097
Parent
bb05299ee78c531…
2 files changed
+66
-41
+1
-1
+66
-41
| --- src/alerts.c | ||
| +++ src/alerts.c | ||
| @@ -575,22 +575,18 @@ | ||
| 575 | 575 | } |
| 576 | 576 | return 0; |
| 577 | 577 | } |
| 578 | 578 | |
| 579 | 579 | /* |
| 580 | -** Make a copy of the input string up to but not including the | |
| 581 | -** first cTerm character. | |
| 582 | -** | |
| 583 | -** Verify that the string really that is to be copied really is a | |
| 584 | -** valid email address. If it is not, then return NULL. | |
| 585 | -** | |
| 586 | -** This routine is more restrictive than necessary. It does not | |
| 587 | -** allow comments, IP address, quoted strings, or certain uncommon | |
| 588 | -** characters. The only non-alphanumerics allowed in the local | |
| 589 | -** part are "_", "+", "-" and "+". | |
| 590 | -*/ | |
| 591 | -char *email_copy_addr(const char *z, char cTerm ){ | |
| 580 | +** Determine whether or not the input string is a valid email address. | |
| 581 | +** Only look at character up to but not including the first \000 or | |
| 582 | +** the first cTerm character, whichever comes first. | |
| 583 | +** | |
| 584 | +** Return the length of the email addresss string in bytes if the email | |
| 585 | +** address is valid. If the email address is misformed, return 0. | |
| 586 | +*/ | |
| 587 | +int email_address_is_valid(const char *z, char cTerm){ | |
| 592 | 588 | int i; |
| 593 | 589 | int nAt = 0; |
| 594 | 590 | int nDot = 0; |
| 595 | 591 | char c; |
| 596 | 592 | if( z[0]=='.' ) return 0; /* Local part cannot begin with "." */ |
| @@ -620,13 +616,28 @@ | ||
| 620 | 616 | } |
| 621 | 617 | } |
| 622 | 618 | if( c!=cTerm ) return 0; /* Missing terminator */ |
| 623 | 619 | if( nAt==0 ) return 0; /* No "@" found anywhere */ |
| 624 | 620 | if( nDot==0 ) return 0; /* No "." in the domain */ |
| 621 | + return i; | |
| 622 | +} | |
| 625 | 623 | |
| 626 | - /* If we reach this point, the email address is valid */ | |
| 627 | - return mprintf("%.*s", i, z); | |
| 624 | +/* | |
| 625 | +** Make a copy of the input string up to but not including the | |
| 626 | +** first cTerm character. | |
| 627 | +** | |
| 628 | +** Verify that the string really that is to be copied really is a | |
| 629 | +** valid email address. If it is not, then return NULL. | |
| 630 | +** | |
| 631 | +** This routine is more restrictive than necessary. It does not | |
| 632 | +** allow comments, IP address, quoted strings, or certain uncommon | |
| 633 | +** characters. The only non-alphanumerics allowed in the local | |
| 634 | +** part are "_", "+", "-" and "+". | |
| 635 | +*/ | |
| 636 | +char *email_copy_addr(const char *z, char cTerm ){ | |
| 637 | + int i = email_address_is_valid(z, cTerm); | |
| 638 | + return i==0 ? 0 : mprintf("%.*s", i, z); | |
| 628 | 639 | } |
| 629 | 640 | |
| 630 | 641 | /* |
| 631 | 642 | ** Scan the input string for a valid email address enclosed in <...> |
| 632 | 643 | ** If the string contains one or more email addresses, extract the first |
| @@ -1516,14 +1527,14 @@ | ||
| 1516 | 1527 | const char *zName = P("name"); |
| 1517 | 1528 | Stmt q; |
| 1518 | 1529 | int sa, sc, sf, st, sw; |
| 1519 | 1530 | int sdigest, sdonotcall, sverified; |
| 1520 | 1531 | int isLogin; /* Logged in as an individual */ |
| 1521 | - const char *ssub; | |
| 1532 | + const char *ssub = 0; | |
| 1522 | 1533 | const char *semail; |
| 1523 | 1534 | const char *smip; |
| 1524 | - const char *suname; | |
| 1535 | + const char *suname = 0; | |
| 1525 | 1536 | const char *mtime; |
| 1526 | 1537 | const char *sctime; |
| 1527 | 1538 | int eErr = 0; |
| 1528 | 1539 | char *zErr = 0; |
| 1529 | 1540 | |
| @@ -1542,22 +1553,24 @@ | ||
| 1542 | 1553 | cgi_redirect("subscribe"); |
| 1543 | 1554 | return; |
| 1544 | 1555 | } |
| 1545 | 1556 | alert_submenu_common(); |
| 1546 | 1557 | if( P("submit")!=0 && cgi_csrf_safe(1) ){ |
| 1547 | - int sdonotcall = PB("sdonotcall"); | |
| 1548 | - int sdigest = PB("sdigest"); | |
| 1549 | - const char *zEmail = P("semail"); | |
| 1550 | - char ssub[10]; | |
| 1558 | + char newSsub[10]; | |
| 1551 | 1559 | int nsub = 0; |
| 1552 | 1560 | Blob update; |
| 1553 | - if( PB("sa") ) ssub[nsub++] = 'a'; | |
| 1554 | - if( g.perm.Read && PB("sc") ) ssub[nsub++] = 'c'; | |
| 1555 | - if( g.perm.RdForum && PB("sf") ) ssub[nsub++] = 'f'; | |
| 1556 | - if( g.perm.RdTkt && PB("st") ) ssub[nsub++] = 't'; | |
| 1557 | - if( g.perm.RdWiki && PB("sw") ) ssub[nsub++] = 'w'; | |
| 1558 | - ssub[nsub] = 0; | |
| 1561 | + | |
| 1562 | + sdonotcall = PB("sdonotcall"); | |
| 1563 | + sdigest = PB("sdigest"); | |
| 1564 | + semail = P("semail"); | |
| 1565 | + if( PB("sa") ) newSsub[nsub++] = 'a'; | |
| 1566 | + if( g.perm.Read && PB("sc") ) newSsub[nsub++] = 'c'; | |
| 1567 | + if( g.perm.RdForum && PB("sf") ) newSsub[nsub++] = 'f'; | |
| 1568 | + if( g.perm.RdTkt && PB("st") ) newSsub[nsub++] = 't'; | |
| 1569 | + if( g.perm.RdWiki && PB("sw") ) newSsub[nsub++] = 'w'; | |
| 1570 | + newSsub[nsub] = 0; | |
| 1571 | + ssub = newSsub; | |
| 1559 | 1572 | blob_init(&update, "UPDATE subscriber SET", -1); |
| 1560 | 1573 | blob_append_sql(&update, |
| 1561 | 1574 | " sdonotcall=%d," |
| 1562 | 1575 | " sdigest=%d," |
| 1563 | 1576 | " ssub=%Q," |
| @@ -1567,25 +1580,31 @@ | ||
| 1567 | 1580 | sdigest, |
| 1568 | 1581 | ssub, |
| 1569 | 1582 | g.zIpAddr |
| 1570 | 1583 | ); |
| 1571 | 1584 | if( g.perm.Admin ){ |
| 1572 | - const char *suname = PT("suname"); | |
| 1573 | - int sverified = PB("sverified"); | |
| 1585 | + suname = PT("suname"); | |
| 1586 | + sverified = PB("sverified"); | |
| 1574 | 1587 | if( suname && suname[0]==0 ) suname = 0; |
| 1575 | 1588 | blob_append_sql(&update, |
| 1576 | 1589 | ", suname=%Q," |
| 1577 | 1590 | " sverified=%d", |
| 1578 | 1591 | suname, |
| 1579 | 1592 | sverified |
| 1580 | 1593 | ); |
| 1581 | 1594 | } |
| 1582 | - if( isLogin && zEmail && zEmail[0] ){ | |
| 1583 | - blob_append_sql(&update, ", semail=%Q", zEmail); | |
| 1595 | + if( isLogin ){ | |
| 1596 | + if( semail==0 || email_address_is_valid(semail,0)==0 ){ | |
| 1597 | + eErr = 8; | |
| 1598 | + } | |
| 1599 | + blob_append_sql(&update, ", semail=%Q", semail); | |
| 1584 | 1600 | } |
| 1585 | 1601 | blob_append_sql(&update," WHERE subscriberCode=hextoblob(%Q)", zName); |
| 1586 | - db_exec_sql(blob_str(&update)); | |
| 1602 | + if( eErr==0 ){ | |
| 1603 | + db_exec_sql(blob_str(&update)); | |
| 1604 | + ssub = 0; | |
| 1605 | + } | |
| 1587 | 1606 | blob_reset(&update); |
| 1588 | 1607 | } |
| 1589 | 1608 | if( P("delete")!=0 && cgi_csrf_safe(1) ){ |
| 1590 | 1609 | if( !PB("dodelete") ){ |
| 1591 | 1610 | eErr = 9; |
| @@ -1594,10 +1613,11 @@ | ||
| 1594 | 1613 | }else{ |
| 1595 | 1614 | alert_unsubscribe(zName); |
| 1596 | 1615 | return; |
| 1597 | 1616 | } |
| 1598 | 1617 | } |
| 1618 | + style_header("Update Subscription"); | |
| 1599 | 1619 | db_prepare(&q, |
| 1600 | 1620 | "SELECT" |
| 1601 | 1621 | " semail," /* 0 */ |
| 1602 | 1622 | " sverified," /* 1 */ |
| 1603 | 1623 | " sdonotcall," /* 2 */ |
| @@ -1611,23 +1631,26 @@ | ||
| 1611 | 1631 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1612 | 1632 | db_finalize(&q); |
| 1613 | 1633 | cgi_redirect("subscribe"); |
| 1614 | 1634 | return; |
| 1615 | 1635 | } |
| 1616 | - style_header("Update Subscription"); | |
| 1617 | - semail = db_column_text(&q, 0); | |
| 1618 | - sverified = db_column_int(&q, 1); | |
| 1619 | - sdonotcall = db_column_int(&q, 2); | |
| 1620 | - sdigest = db_column_int(&q, 3); | |
| 1621 | - ssub = db_column_text(&q, 4); | |
| 1636 | + if( ssub==0 ){ | |
| 1637 | + semail = db_column_text(&q, 0); | |
| 1638 | + sdonotcall = db_column_int(&q, 2); | |
| 1639 | + sdigest = db_column_int(&q, 3); | |
| 1640 | + ssub = db_column_text(&q, 4); | |
| 1641 | + } | |
| 1642 | + if( suname==0 ){ | |
| 1643 | + suname = db_column_text(&q, 6); | |
| 1644 | + sverified = db_column_int(&q, 1); | |
| 1645 | + } | |
| 1622 | 1646 | sa = strchr(ssub,'a')!=0; |
| 1623 | 1647 | sc = strchr(ssub,'c')!=0; |
| 1624 | 1648 | sf = strchr(ssub,'f')!=0; |
| 1625 | 1649 | st = strchr(ssub,'t')!=0; |
| 1626 | 1650 | sw = strchr(ssub,'w')!=0; |
| 1627 | 1651 | smip = db_column_text(&q, 5); |
| 1628 | - suname = db_column_text(&q, 6); | |
| 1629 | 1652 | mtime = db_column_text(&q, 7); |
| 1630 | 1653 | sctime = db_column_text(&q, 8); |
| 1631 | 1654 | if( !g.perm.Admin && !sverified ){ |
| 1632 | 1655 | db_multi_exec( |
| 1633 | 1656 | "UPDATE subscriber SET sverified=1 WHERE subscriberCode=hextoblob(%Q)", |
| @@ -1645,13 +1668,15 @@ | ||
| 1645 | 1668 | @ <table class="subscribe"> |
| 1646 | 1669 | @ <tr> |
| 1647 | 1670 | @ <td class="form_label">Email Address:</td> |
| 1648 | 1671 | if( isLogin ){ |
| 1649 | 1672 | @ <td><input type="text" name="semail" value="%h(semail)" size="30">\ |
| 1650 | - if( g.perm.Admin ){ | |
| 1651 | - @ <a href="%R/announce?to=%t(semail)">\ | |
| 1652 | - @ (Send a message to %h(semail))</a>\ | |
| 1673 | + if( eErr==8 ){ | |
| 1674 | + @ <span class='loginError'>← not a valid email address!</span> | |
| 1675 | + }else if( g.perm.Admin ){ | |
| 1676 | + @ <a href="%R/announce?to=%t(semail)">\ | |
| 1677 | + @ (Send a message to %h(semail))</a>\ | |
| 1653 | 1678 | } |
| 1654 | 1679 | @ </td> |
| 1655 | 1680 | }else{ |
| 1656 | 1681 | @ <td>%h(semail)</td> |
| 1657 | 1682 | } |
| 1658 | 1683 |
| --- src/alerts.c | |
| +++ src/alerts.c | |
| @@ -575,22 +575,18 @@ | |
| 575 | } |
| 576 | return 0; |
| 577 | } |
| 578 | |
| 579 | /* |
| 580 | ** Make a copy of the input string up to but not including the |
| 581 | ** first cTerm character. |
| 582 | ** |
| 583 | ** Verify that the string really that is to be copied really is a |
| 584 | ** valid email address. If it is not, then return NULL. |
| 585 | ** |
| 586 | ** This routine is more restrictive than necessary. It does not |
| 587 | ** allow comments, IP address, quoted strings, or certain uncommon |
| 588 | ** characters. The only non-alphanumerics allowed in the local |
| 589 | ** part are "_", "+", "-" and "+". |
| 590 | */ |
| 591 | char *email_copy_addr(const char *z, char cTerm ){ |
| 592 | int i; |
| 593 | int nAt = 0; |
| 594 | int nDot = 0; |
| 595 | char c; |
| 596 | if( z[0]=='.' ) return 0; /* Local part cannot begin with "." */ |
| @@ -620,13 +616,28 @@ | |
| 620 | } |
| 621 | } |
| 622 | if( c!=cTerm ) return 0; /* Missing terminator */ |
| 623 | if( nAt==0 ) return 0; /* No "@" found anywhere */ |
| 624 | if( nDot==0 ) return 0; /* No "." in the domain */ |
| 625 | |
| 626 | /* If we reach this point, the email address is valid */ |
| 627 | return mprintf("%.*s", i, z); |
| 628 | } |
| 629 | |
| 630 | /* |
| 631 | ** Scan the input string for a valid email address enclosed in <...> |
| 632 | ** If the string contains one or more email addresses, extract the first |
| @@ -1516,14 +1527,14 @@ | |
| 1516 | const char *zName = P("name"); |
| 1517 | Stmt q; |
| 1518 | int sa, sc, sf, st, sw; |
| 1519 | int sdigest, sdonotcall, sverified; |
| 1520 | int isLogin; /* Logged in as an individual */ |
| 1521 | const char *ssub; |
| 1522 | const char *semail; |
| 1523 | const char *smip; |
| 1524 | const char *suname; |
| 1525 | const char *mtime; |
| 1526 | const char *sctime; |
| 1527 | int eErr = 0; |
| 1528 | char *zErr = 0; |
| 1529 | |
| @@ -1542,22 +1553,24 @@ | |
| 1542 | cgi_redirect("subscribe"); |
| 1543 | return; |
| 1544 | } |
| 1545 | alert_submenu_common(); |
| 1546 | if( P("submit")!=0 && cgi_csrf_safe(1) ){ |
| 1547 | int sdonotcall = PB("sdonotcall"); |
| 1548 | int sdigest = PB("sdigest"); |
| 1549 | const char *zEmail = P("semail"); |
| 1550 | char ssub[10]; |
| 1551 | int nsub = 0; |
| 1552 | Blob update; |
| 1553 | if( PB("sa") ) ssub[nsub++] = 'a'; |
| 1554 | if( g.perm.Read && PB("sc") ) ssub[nsub++] = 'c'; |
| 1555 | if( g.perm.RdForum && PB("sf") ) ssub[nsub++] = 'f'; |
| 1556 | if( g.perm.RdTkt && PB("st") ) ssub[nsub++] = 't'; |
| 1557 | if( g.perm.RdWiki && PB("sw") ) ssub[nsub++] = 'w'; |
| 1558 | ssub[nsub] = 0; |
| 1559 | blob_init(&update, "UPDATE subscriber SET", -1); |
| 1560 | blob_append_sql(&update, |
| 1561 | " sdonotcall=%d," |
| 1562 | " sdigest=%d," |
| 1563 | " ssub=%Q," |
| @@ -1567,25 +1580,31 @@ | |
| 1567 | sdigest, |
| 1568 | ssub, |
| 1569 | g.zIpAddr |
| 1570 | ); |
| 1571 | if( g.perm.Admin ){ |
| 1572 | const char *suname = PT("suname"); |
| 1573 | int sverified = PB("sverified"); |
| 1574 | if( suname && suname[0]==0 ) suname = 0; |
| 1575 | blob_append_sql(&update, |
| 1576 | ", suname=%Q," |
| 1577 | " sverified=%d", |
| 1578 | suname, |
| 1579 | sverified |
| 1580 | ); |
| 1581 | } |
| 1582 | if( isLogin && zEmail && zEmail[0] ){ |
| 1583 | blob_append_sql(&update, ", semail=%Q", zEmail); |
| 1584 | } |
| 1585 | blob_append_sql(&update," WHERE subscriberCode=hextoblob(%Q)", zName); |
| 1586 | db_exec_sql(blob_str(&update)); |
| 1587 | blob_reset(&update); |
| 1588 | } |
| 1589 | if( P("delete")!=0 && cgi_csrf_safe(1) ){ |
| 1590 | if( !PB("dodelete") ){ |
| 1591 | eErr = 9; |
| @@ -1594,10 +1613,11 @@ | |
| 1594 | }else{ |
| 1595 | alert_unsubscribe(zName); |
| 1596 | return; |
| 1597 | } |
| 1598 | } |
| 1599 | db_prepare(&q, |
| 1600 | "SELECT" |
| 1601 | " semail," /* 0 */ |
| 1602 | " sverified," /* 1 */ |
| 1603 | " sdonotcall," /* 2 */ |
| @@ -1611,23 +1631,26 @@ | |
| 1611 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1612 | db_finalize(&q); |
| 1613 | cgi_redirect("subscribe"); |
| 1614 | return; |
| 1615 | } |
| 1616 | style_header("Update Subscription"); |
| 1617 | semail = db_column_text(&q, 0); |
| 1618 | sverified = db_column_int(&q, 1); |
| 1619 | sdonotcall = db_column_int(&q, 2); |
| 1620 | sdigest = db_column_int(&q, 3); |
| 1621 | ssub = db_column_text(&q, 4); |
| 1622 | sa = strchr(ssub,'a')!=0; |
| 1623 | sc = strchr(ssub,'c')!=0; |
| 1624 | sf = strchr(ssub,'f')!=0; |
| 1625 | st = strchr(ssub,'t')!=0; |
| 1626 | sw = strchr(ssub,'w')!=0; |
| 1627 | smip = db_column_text(&q, 5); |
| 1628 | suname = db_column_text(&q, 6); |
| 1629 | mtime = db_column_text(&q, 7); |
| 1630 | sctime = db_column_text(&q, 8); |
| 1631 | if( !g.perm.Admin && !sverified ){ |
| 1632 | db_multi_exec( |
| 1633 | "UPDATE subscriber SET sverified=1 WHERE subscriberCode=hextoblob(%Q)", |
| @@ -1645,13 +1668,15 @@ | |
| 1645 | @ <table class="subscribe"> |
| 1646 | @ <tr> |
| 1647 | @ <td class="form_label">Email Address:</td> |
| 1648 | if( isLogin ){ |
| 1649 | @ <td><input type="text" name="semail" value="%h(semail)" size="30">\ |
| 1650 | if( g.perm.Admin ){ |
| 1651 | @ <a href="%R/announce?to=%t(semail)">\ |
| 1652 | @ (Send a message to %h(semail))</a>\ |
| 1653 | } |
| 1654 | @ </td> |
| 1655 | }else{ |
| 1656 | @ <td>%h(semail)</td> |
| 1657 | } |
| 1658 |
| --- src/alerts.c | |
| +++ src/alerts.c | |
| @@ -575,22 +575,18 @@ | |
| 575 | } |
| 576 | return 0; |
| 577 | } |
| 578 | |
| 579 | /* |
| 580 | ** Determine whether or not the input string is a valid email address. |
| 581 | ** Only look at character up to but not including the first \000 or |
| 582 | ** the first cTerm character, whichever comes first. |
| 583 | ** |
| 584 | ** Return the length of the email addresss string in bytes if the email |
| 585 | ** address is valid. If the email address is misformed, return 0. |
| 586 | */ |
| 587 | int email_address_is_valid(const char *z, char cTerm){ |
| 588 | int i; |
| 589 | int nAt = 0; |
| 590 | int nDot = 0; |
| 591 | char c; |
| 592 | if( z[0]=='.' ) return 0; /* Local part cannot begin with "." */ |
| @@ -620,13 +616,28 @@ | |
| 616 | } |
| 617 | } |
| 618 | if( c!=cTerm ) return 0; /* Missing terminator */ |
| 619 | if( nAt==0 ) return 0; /* No "@" found anywhere */ |
| 620 | if( nDot==0 ) return 0; /* No "." in the domain */ |
| 621 | return i; |
| 622 | } |
| 623 | |
| 624 | /* |
| 625 | ** Make a copy of the input string up to but not including the |
| 626 | ** first cTerm character. |
| 627 | ** |
| 628 | ** Verify that the string really that is to be copied really is a |
| 629 | ** valid email address. If it is not, then return NULL. |
| 630 | ** |
| 631 | ** This routine is more restrictive than necessary. It does not |
| 632 | ** allow comments, IP address, quoted strings, or certain uncommon |
| 633 | ** characters. The only non-alphanumerics allowed in the local |
| 634 | ** part are "_", "+", "-" and "+". |
| 635 | */ |
| 636 | char *email_copy_addr(const char *z, char cTerm ){ |
| 637 | int i = email_address_is_valid(z, cTerm); |
| 638 | return i==0 ? 0 : mprintf("%.*s", i, z); |
| 639 | } |
| 640 | |
| 641 | /* |
| 642 | ** Scan the input string for a valid email address enclosed in <...> |
| 643 | ** If the string contains one or more email addresses, extract the first |
| @@ -1516,14 +1527,14 @@ | |
| 1527 | const char *zName = P("name"); |
| 1528 | Stmt q; |
| 1529 | int sa, sc, sf, st, sw; |
| 1530 | int sdigest, sdonotcall, sverified; |
| 1531 | int isLogin; /* Logged in as an individual */ |
| 1532 | const char *ssub = 0; |
| 1533 | const char *semail; |
| 1534 | const char *smip; |
| 1535 | const char *suname = 0; |
| 1536 | const char *mtime; |
| 1537 | const char *sctime; |
| 1538 | int eErr = 0; |
| 1539 | char *zErr = 0; |
| 1540 | |
| @@ -1542,22 +1553,24 @@ | |
| 1553 | cgi_redirect("subscribe"); |
| 1554 | return; |
| 1555 | } |
| 1556 | alert_submenu_common(); |
| 1557 | if( P("submit")!=0 && cgi_csrf_safe(1) ){ |
| 1558 | char newSsub[10]; |
| 1559 | int nsub = 0; |
| 1560 | Blob update; |
| 1561 | |
| 1562 | sdonotcall = PB("sdonotcall"); |
| 1563 | sdigest = PB("sdigest"); |
| 1564 | semail = P("semail"); |
| 1565 | if( PB("sa") ) newSsub[nsub++] = 'a'; |
| 1566 | if( g.perm.Read && PB("sc") ) newSsub[nsub++] = 'c'; |
| 1567 | if( g.perm.RdForum && PB("sf") ) newSsub[nsub++] = 'f'; |
| 1568 | if( g.perm.RdTkt && PB("st") ) newSsub[nsub++] = 't'; |
| 1569 | if( g.perm.RdWiki && PB("sw") ) newSsub[nsub++] = 'w'; |
| 1570 | newSsub[nsub] = 0; |
| 1571 | ssub = newSsub; |
| 1572 | blob_init(&update, "UPDATE subscriber SET", -1); |
| 1573 | blob_append_sql(&update, |
| 1574 | " sdonotcall=%d," |
| 1575 | " sdigest=%d," |
| 1576 | " ssub=%Q," |
| @@ -1567,25 +1580,31 @@ | |
| 1580 | sdigest, |
| 1581 | ssub, |
| 1582 | g.zIpAddr |
| 1583 | ); |
| 1584 | if( g.perm.Admin ){ |
| 1585 | suname = PT("suname"); |
| 1586 | sverified = PB("sverified"); |
| 1587 | if( suname && suname[0]==0 ) suname = 0; |
| 1588 | blob_append_sql(&update, |
| 1589 | ", suname=%Q," |
| 1590 | " sverified=%d", |
| 1591 | suname, |
| 1592 | sverified |
| 1593 | ); |
| 1594 | } |
| 1595 | if( isLogin ){ |
| 1596 | if( semail==0 || email_address_is_valid(semail,0)==0 ){ |
| 1597 | eErr = 8; |
| 1598 | } |
| 1599 | blob_append_sql(&update, ", semail=%Q", semail); |
| 1600 | } |
| 1601 | blob_append_sql(&update," WHERE subscriberCode=hextoblob(%Q)", zName); |
| 1602 | if( eErr==0 ){ |
| 1603 | db_exec_sql(blob_str(&update)); |
| 1604 | ssub = 0; |
| 1605 | } |
| 1606 | blob_reset(&update); |
| 1607 | } |
| 1608 | if( P("delete")!=0 && cgi_csrf_safe(1) ){ |
| 1609 | if( !PB("dodelete") ){ |
| 1610 | eErr = 9; |
| @@ -1594,10 +1613,11 @@ | |
| 1613 | }else{ |
| 1614 | alert_unsubscribe(zName); |
| 1615 | return; |
| 1616 | } |
| 1617 | } |
| 1618 | style_header("Update Subscription"); |
| 1619 | db_prepare(&q, |
| 1620 | "SELECT" |
| 1621 | " semail," /* 0 */ |
| 1622 | " sverified," /* 1 */ |
| 1623 | " sdonotcall," /* 2 */ |
| @@ -1611,23 +1631,26 @@ | |
| 1631 | if( db_step(&q)!=SQLITE_ROW ){ |
| 1632 | db_finalize(&q); |
| 1633 | cgi_redirect("subscribe"); |
| 1634 | return; |
| 1635 | } |
| 1636 | if( ssub==0 ){ |
| 1637 | semail = db_column_text(&q, 0); |
| 1638 | sdonotcall = db_column_int(&q, 2); |
| 1639 | sdigest = db_column_int(&q, 3); |
| 1640 | ssub = db_column_text(&q, 4); |
| 1641 | } |
| 1642 | if( suname==0 ){ |
| 1643 | suname = db_column_text(&q, 6); |
| 1644 | sverified = db_column_int(&q, 1); |
| 1645 | } |
| 1646 | sa = strchr(ssub,'a')!=0; |
| 1647 | sc = strchr(ssub,'c')!=0; |
| 1648 | sf = strchr(ssub,'f')!=0; |
| 1649 | st = strchr(ssub,'t')!=0; |
| 1650 | sw = strchr(ssub,'w')!=0; |
| 1651 | smip = db_column_text(&q, 5); |
| 1652 | mtime = db_column_text(&q, 7); |
| 1653 | sctime = db_column_text(&q, 8); |
| 1654 | if( !g.perm.Admin && !sverified ){ |
| 1655 | db_multi_exec( |
| 1656 | "UPDATE subscriber SET sverified=1 WHERE subscriberCode=hextoblob(%Q)", |
| @@ -1645,13 +1668,15 @@ | |
| 1668 | @ <table class="subscribe"> |
| 1669 | @ <tr> |
| 1670 | @ <td class="form_label">Email Address:</td> |
| 1671 | if( isLogin ){ |
| 1672 | @ <td><input type="text" name="semail" value="%h(semail)" size="30">\ |
| 1673 | if( eErr==8 ){ |
| 1674 | @ <span class='loginError'>← not a valid email address!</span> |
| 1675 | }else if( g.perm.Admin ){ |
| 1676 | @ <a href="%R/announce?to=%t(semail)">\ |
| 1677 | @ (Send a message to %h(semail))</a>\ |
| 1678 | } |
| 1679 | @ </td> |
| 1680 | }else{ |
| 1681 | @ <td>%h(semail)</td> |
| 1682 | } |
| 1683 |
+1
-1
| --- src/login.c | ||
| +++ src/login.c | ||
| @@ -1544,11 +1544,11 @@ | ||
| 1544 | 1544 | iErrLine = 2; |
| 1545 | 1545 | zErr = "Required"; |
| 1546 | 1546 | }else if( zEAddr[0]==0 ){ |
| 1547 | 1547 | iErrLine = 3; |
| 1548 | 1548 | zErr = "Required"; |
| 1549 | - }else if( email_copy_addr(zEAddr,0)==0 ){ | |
| 1549 | + }else if( email_address_is_valid(zEAddr,0)==0 ){ | |
| 1550 | 1550 | iErrLine = 3; |
| 1551 | 1551 | zErr = "Not a valid email address"; |
| 1552 | 1552 | }else if( strlen(zPasswd)<6 ){ |
| 1553 | 1553 | iErrLine = 4; |
| 1554 | 1554 | zErr = "Password must be at least 6 characters long"; |
| 1555 | 1555 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1544,11 +1544,11 @@ | |
| 1544 | iErrLine = 2; |
| 1545 | zErr = "Required"; |
| 1546 | }else if( zEAddr[0]==0 ){ |
| 1547 | iErrLine = 3; |
| 1548 | zErr = "Required"; |
| 1549 | }else if( email_copy_addr(zEAddr,0)==0 ){ |
| 1550 | iErrLine = 3; |
| 1551 | zErr = "Not a valid email address"; |
| 1552 | }else if( strlen(zPasswd)<6 ){ |
| 1553 | iErrLine = 4; |
| 1554 | zErr = "Password must be at least 6 characters long"; |
| 1555 |
| --- src/login.c | |
| +++ src/login.c | |
| @@ -1544,11 +1544,11 @@ | |
| 1544 | iErrLine = 2; |
| 1545 | zErr = "Required"; |
| 1546 | }else if( zEAddr[0]==0 ){ |
| 1547 | iErrLine = 3; |
| 1548 | zErr = "Required"; |
| 1549 | }else if( email_address_is_valid(zEAddr,0)==0 ){ |
| 1550 | iErrLine = 3; |
| 1551 | zErr = "Not a valid email address"; |
| 1552 | }else if( strlen(zPasswd)<6 ){ |
| 1553 | iErrLine = 4; |
| 1554 | zErr = "Password must be at least 6 characters long"; |
| 1555 |