comparison src/core/ngx_string.c @ 6009:15a15f6ae3a2

Core: overflow detection in number parsing functions.
author Ruslan Ermilov <ru@nginx.com>
date Tue, 17 Mar 2015 00:26:15 +0300
parents 78271500b8de
children fcbac620ae83
comparison
equal deleted inserted replaced
6008:b92d5a26d55f 6009:15a15f6ae3a2
899 899
900 900
901 ngx_int_t 901 ngx_int_t
902 ngx_atoi(u_char *line, size_t n) 902 ngx_atoi(u_char *line, size_t n)
903 { 903 {
904 ngx_int_t value; 904 ngx_int_t value, cutoff, cutlim;
905 905
906 if (n == 0) { 906 if (n == 0) {
907 return NGX_ERROR; 907 return NGX_ERROR;
908 } 908 }
909
910 cutoff = NGX_MAX_INT_T_VALUE / 10;
911 cutlim = NGX_MAX_INT_T_VALUE % 10;
909 912
910 for (value = 0; n--; line++) { 913 for (value = 0; n--; line++) {
911 if (*line < '0' || *line > '9') { 914 if (*line < '0' || *line > '9') {
912 return NGX_ERROR; 915 return NGX_ERROR;
913 } 916 }
914 917
918 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
919 return NGX_ERROR;
920 }
921
915 value = value * 10 + (*line - '0'); 922 value = value * 10 + (*line - '0');
916 } 923 }
917 924
918 if (value < 0) { 925 return value;
919 return NGX_ERROR;
920
921 } else {
922 return value;
923 }
924 } 926 }
925 927
926 928
927 /* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */ 929 /* parse a fixed point number, e.g., ngx_atofp("10.5", 4, 2) returns 1050 */
928 930
929 ngx_int_t 931 ngx_int_t
930 ngx_atofp(u_char *line, size_t n, size_t point) 932 ngx_atofp(u_char *line, size_t n, size_t point)
931 { 933 {
932 ngx_int_t value; 934 ngx_int_t value, cutoff, cutlim;
933 ngx_uint_t dot; 935 ngx_uint_t dot;
934 936
935 if (n == 0) { 937 if (n == 0) {
936 return NGX_ERROR; 938 return NGX_ERROR;
937 } 939 }
940
941 cutoff = NGX_MAX_INT_T_VALUE / 10;
942 cutlim = NGX_MAX_INT_T_VALUE % 10;
938 943
939 dot = 0; 944 dot = 0;
940 945
941 for (value = 0; n--; line++) { 946 for (value = 0; n--; line++) {
942 947
955 960
956 if (*line < '0' || *line > '9') { 961 if (*line < '0' || *line > '9') {
957 return NGX_ERROR; 962 return NGX_ERROR;
958 } 963 }
959 964
965 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
966 return NGX_ERROR;
967 }
968
960 value = value * 10 + (*line - '0'); 969 value = value * 10 + (*line - '0');
961 point -= dot; 970 point -= dot;
962 } 971 }
963 972
964 while (point--) { 973 while (point--) {
974 if (value > cutoff) {
975 return NGX_ERROR;
976 }
977
965 value = value * 10; 978 value = value * 10;
966 } 979 }
967 980
968 if (value < 0) { 981 return value;
969 return NGX_ERROR;
970
971 } else {
972 return value;
973 }
974 } 982 }
975 983
976 984
977 ssize_t 985 ssize_t
978 ngx_atosz(u_char *line, size_t n) 986 ngx_atosz(u_char *line, size_t n)
979 { 987 {
980 ssize_t value; 988 ssize_t value, cutoff, cutlim;
981 989
982 if (n == 0) { 990 if (n == 0) {
983 return NGX_ERROR; 991 return NGX_ERROR;
984 } 992 }
993
994 cutoff = NGX_MAX_SIZE_T_VALUE / 10;
995 cutlim = NGX_MAX_SIZE_T_VALUE % 10;
985 996
986 for (value = 0; n--; line++) { 997 for (value = 0; n--; line++) {
987 if (*line < '0' || *line > '9') { 998 if (*line < '0' || *line > '9') {
988 return NGX_ERROR; 999 return NGX_ERROR;
989 } 1000 }
990 1001
1002 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
1003 return NGX_ERROR;
1004 }
1005
991 value = value * 10 + (*line - '0'); 1006 value = value * 10 + (*line - '0');
992 } 1007 }
993 1008
994 if (value < 0) { 1009 return value;
995 return NGX_ERROR;
996
997 } else {
998 return value;
999 }
1000 } 1010 }
1001 1011
1002 1012
1003 off_t 1013 off_t
1004 ngx_atoof(u_char *line, size_t n) 1014 ngx_atoof(u_char *line, size_t n)
1005 { 1015 {
1006 off_t value; 1016 off_t value, cutoff, cutlim;
1007 1017
1008 if (n == 0) { 1018 if (n == 0) {
1009 return NGX_ERROR; 1019 return NGX_ERROR;
1010 } 1020 }
1021
1022 cutoff = NGX_MAX_OFF_T_VALUE / 10;
1023 cutlim = NGX_MAX_OFF_T_VALUE % 10;
1011 1024
1012 for (value = 0; n--; line++) { 1025 for (value = 0; n--; line++) {
1013 if (*line < '0' || *line > '9') { 1026 if (*line < '0' || *line > '9') {
1014 return NGX_ERROR; 1027 return NGX_ERROR;
1015 } 1028 }
1016 1029
1030 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
1031 return NGX_ERROR;
1032 }
1033
1017 value = value * 10 + (*line - '0'); 1034 value = value * 10 + (*line - '0');
1018 } 1035 }
1019 1036
1020 if (value < 0) { 1037 return value;
1021 return NGX_ERROR;
1022
1023 } else {
1024 return value;
1025 }
1026 } 1038 }
1027 1039
1028 1040
1029 time_t 1041 time_t
1030 ngx_atotm(u_char *line, size_t n) 1042 ngx_atotm(u_char *line, size_t n)
1031 { 1043 {
1032 time_t value; 1044 time_t value, cutoff, cutlim;
1033 1045
1034 if (n == 0) { 1046 if (n == 0) {
1035 return NGX_ERROR; 1047 return NGX_ERROR;
1036 } 1048 }
1049
1050 cutoff = NGX_MAX_TIME_T_VALUE / 10;
1051 cutlim = NGX_MAX_TIME_T_VALUE % 10;
1037 1052
1038 for (value = 0; n--; line++) { 1053 for (value = 0; n--; line++) {
1039 if (*line < '0' || *line > '9') { 1054 if (*line < '0' || *line > '9') {
1040 return NGX_ERROR; 1055 return NGX_ERROR;
1041 } 1056 }
1042 1057
1058 if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
1059 return NGX_ERROR;
1060 }
1061
1043 value = value * 10 + (*line - '0'); 1062 value = value * 10 + (*line - '0');
1044 } 1063 }
1045 1064
1046 if (value < 0) { 1065 return value;
1047 return NGX_ERROR;
1048
1049 } else {
1050 return value;
1051 }
1052 } 1066 }
1053 1067
1054 1068
1055 ngx_int_t 1069 ngx_int_t
1056 ngx_hextoi(u_char *line, size_t n) 1070 ngx_hextoi(u_char *line, size_t n)
1057 { 1071 {
1058 u_char c, ch; 1072 u_char c, ch;
1059 ngx_int_t value; 1073 ngx_int_t value, cutoff;
1060 1074
1061 if (n == 0) { 1075 if (n == 0) {
1062 return NGX_ERROR; 1076 return NGX_ERROR;
1063 } 1077 }
1064 1078
1079 cutoff = NGX_MAX_INT_T_VALUE / 16;
1080
1065 for (value = 0; n--; line++) { 1081 for (value = 0; n--; line++) {
1082 if (value > cutoff) {
1083 return NGX_ERROR;
1084 }
1085
1066 ch = *line; 1086 ch = *line;
1067 1087
1068 if (ch >= '0' && ch <= '9') { 1088 if (ch >= '0' && ch <= '9') {
1069 value = value * 16 + (ch - '0'); 1089 value = value * 16 + (ch - '0');
1070 continue; 1090 continue;
1078 } 1098 }
1079 1099
1080 return NGX_ERROR; 1100 return NGX_ERROR;
1081 } 1101 }
1082 1102
1083 if (value < 0) { 1103 return value;
1084 return NGX_ERROR;
1085
1086 } else {
1087 return value;
1088 }
1089 } 1104 }
1090 1105
1091 1106
1092 u_char * 1107 u_char *
1093 ngx_hex_dump(u_char *dst, u_char *src, size_t len) 1108 ngx_hex_dump(u_char *dst, u_char *src, size_t len)