diff --git a/all.sas b/all.sas index aa5a768..5d2e8aa 100644 --- a/all.sas +++ b/all.sas @@ -5883,7 +5883,8 @@ data &outds; /*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32 OPERATOR_NM $10 RAW_VALUE $4000;*/ set &inds; - length reason_cd $4032 vtype $1 vnum dsid 8; + length reason_cd $4032 vtype $1 vnum dsid 8 tmp $4000; + drop tmp; /* quick check to ensure column exists */ if upcase(VARIABLE_NM) not in @@ -5959,18 +5960,32 @@ data &outds; end; /* special logic */ - if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',''); - else if OPERATOR_NM in ('IN','NOT IN') then do; - if substr(raw_value,1,1) ne '(' - or substr(cats(reverse(raw_value)),1,1) ne ')' - then do; - REASON_CD='Missing start/end bracket in RAW_VALUE'; - putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; - call symputx('reason_cd',reason_cd,'l'); - call symputx('nobs',_n_,'l'); - output; + if OPERATOR_NM in ('IN','NOT IN','BETWEEN') then do; + if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',','); + else do; + if substr(raw_value,1,1) ne '(' + or substr(cats(reverse(raw_value)),1,1) ne ')' + then do; + REASON_CD='Missing start/end bracket in RAW_VALUE'; + putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; + call symputx('reason_cd',reason_cd,'l'); + call symputx('nobs',_n_,'l'); + output; + end; + else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0)); + /* we now have a comma seperated list of values */ + if vtype='N' then do i=1 to countc(raw_value1, ',')+1; + tmp=scan(raw_value1,i,','); + if cats(tmp) ne '.' and input(tmp, ?? 8.) eq . then do; + REASON_CD='Non Numeric value provided'; + putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; + call symputx('reason_cd',reason_cd,'l'); + call symputx('nobs',_n_,'l'); + output; + end; + return; + end; end; - else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0)); end; else raw_value1=raw_value; diff --git a/base/mp_filtercheck.sas b/base/mp_filtercheck.sas index 69c5cd2..f10f0c7 100644 --- a/base/mp_filtercheck.sas +++ b/base/mp_filtercheck.sas @@ -92,7 +92,8 @@ data &outds; /*length GROUP_LOGIC SUBGROUP_LOGIC $3 SUBGROUP_ID 8 VARIABLE_NM $32 OPERATOR_NM $10 RAW_VALUE $4000;*/ set &inds; - length reason_cd $4032 vtype $1 vnum dsid 8; + length reason_cd $4032 vtype $1 vnum dsid 8 tmp $4000; + drop tmp; /* quick check to ensure column exists */ if upcase(VARIABLE_NM) not in @@ -168,18 +169,32 @@ data &outds; end; /* special logic */ - if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',''); - else if OPERATOR_NM in ('IN','NOT IN') then do; - if substr(raw_value,1,1) ne '(' - or substr(cats(reverse(raw_value)),1,1) ne ')' - then do; - REASON_CD='Missing start/end bracket in RAW_VALUE'; - putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; - call symputx('reason_cd',reason_cd,'l'); - call symputx('nobs',_n_,'l'); - output; + if OPERATOR_NM in ('IN','NOT IN','BETWEEN') then do; + if OPERATOR_NM='BETWEEN' then raw_value1=tranwrd(raw_value,' AND ',','); + else do; + if substr(raw_value,1,1) ne '(' + or substr(cats(reverse(raw_value)),1,1) ne ')' + then do; + REASON_CD='Missing start/end bracket in RAW_VALUE'; + putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; + call symputx('reason_cd',reason_cd,'l'); + call symputx('nobs',_n_,'l'); + output; + end; + else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0)); + /* we now have a comma seperated list of values */ + if vtype='N' then do i=1 to countc(raw_value1, ',')+1; + tmp=scan(raw_value1,i,','); + if cats(tmp) ne '.' and input(tmp, ?? 8.) eq . then do; + REASON_CD='Non Numeric value provided'; + putlog REASON_CD= OPERATOR_NM= raw_value= raw_value1= ; + call symputx('reason_cd',reason_cd,'l'); + call symputx('nobs',_n_,'l'); + output; + end; + return; + end; end; - else raw_value1=substr(raw_value,2,max(length(raw_value)-2,0)); end; else raw_value1=raw_value; diff --git a/sasjs/sasjsconfig.json b/sasjs/sasjsconfig.json index e900f79..ae89c0e 100644 --- a/sasjs/sasjsconfig.json +++ b/sasjs/sasjsconfig.json @@ -67,7 +67,7 @@ }, { "name": "server", - "serverUrl": "", + "serverUrl": "https://sas.4gl.io", "serverType": "SASJS", "httpsAgentOptions": { "allowInsecureRequests": false @@ -107,4 +107,4 @@ "contextName": "SAS Job Execution compute context" } ] -} +} \ No newline at end of file diff --git a/tests/base/mp_filtercheck.test.sas b/tests/base/mp_filtercheck.test.sas index 49d5b04..b1e07e0 100644 --- a/tests/base/mp_filtercheck.test.sas +++ b/tests/base/mp_filtercheck.test.sas @@ -38,7 +38,7 @@ William,M,15,66.5,112 ;;;; run; -/* valid filter conditions */ +/* VALID filter conditions */ data work.inds; infile datalines4 dsd; input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. @@ -51,6 +51,7 @@ AND,OR,2,Weight,>=,77.7 AND,OR,2,Weight,NE,77.7 AND,AND,1,age,=,.A AND,AND,1,height,<,.B +AND,AND,1,age,IN,"(.a,.b,.)" ;;;; run; @@ -115,6 +116,28 @@ run; outds=work.test_results ) +/* invalid IN value */ +data work.inds; + infile datalines4 dsd; + input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. + OPERATOR_NM:$10. RAW_VALUE:$4000.; +datalines4; +AND,OR,2,age,IN,"(.,.a,X)" +;;;; +run; + +%mp_filtercheck(work.inds, + targetds=work.class, + outds=work.badrecords, + abort=NO +) +%let syscc=0; +%mp_assertdsobs(work.badrecords, + desc=Invalid IN value, + test=HASOBS, + outds=work.test_results +) + /* Code injection - column name */ data work.inds; infile datalines4 dsd; @@ -163,7 +186,7 @@ run; data work.inds; infile datalines4 dsd; input GROUP_LOGIC:$3. SUBGROUP_LOGIC:$3. SUBGROUP_ID:8. VARIABLE_NM:$32. - OPERATOR_NM:$10. RAW_VALUE:8; + OPERATOR_NM:$10. RAW_VALUE:8.; datalines4; AND,AND,1,age,=,0 ;;;;