comparison src/core/ngx_string.c @ 6083:516d8e299273 stable-1.6

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