Browse code

core expr eval: undef conversion to int and str

(int)(undef)=0
(str)(undef)=""

Andrei Pelinescu-Onciul authored on 28/04/2009 08:50:56
Showing 1 changed files
... ...
@@ -668,6 +668,15 @@ int rve_check_type(enum rval_type* type, struct rval_expr* rve,
668 668
 
669 669
 /** get the integer value of an rvalue.
670 670
   * *i=(int)rv
671
+  * if rv == undefined select, avp or pvar, return 0.
672
+  * if an error occurs while evaluating a select, avp or pvar, behave as
673
+  * for the undefined case (and return success).
674
+  * @param h - script context handle
675
+  * @param msg - sip msg
676
+  * @param i   - pointer to int, where the conversion result will be stored
677
+  * @param rv   - rvalue to be converted
678
+  * @param cache - cached rv value (read-only), can be 0
679
+  *
671 680
   * @return 0 on success, \<0 on error and EXPR_DROP on drop
672 681
  */
673 682
 int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
... ...
@@ -705,7 +714,9 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
705 714
 					*i=cache->c.avp_val.n;
706 715
 				}else if (cache->val_type==RV_STR)
707 716
 					goto rv_str;
708
-				else goto error;
717
+				else if (cache->val_type==RV_NONE)
718
+					goto undef;
719
+				else goto error_cache;
709 720
 			}else{
710 721
 				r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
711 722
 											&avp_val, rv->v.avps.index);
... ...
@@ -716,7 +727,7 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
716 727
 						*i=avp_val.n;
717 728
 					}
718 729
 				}else{
719
-					goto error;
730
+					goto undef;
720 731
 				}
721 732
 			}
722 733
 			break;
... ...
@@ -727,7 +738,9 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
727 738
 					*i=cache->c.pval.ri;
728 739
 				}else if (cache->val_type==RV_STR)
729 740
 					goto rv_str;
730
-				else goto error;
741
+				else if (cache->val_type==RV_NONE)
742
+					goto undef;
743
+				else goto error_cache;
731 744
 			}else{
732 745
 				memset(&pval, 0, sizeof(pval));
733 746
 				if (likely(pv_get_spec_value(msg, &rv->v.pvs, &pval)==0)){
... ...
@@ -738,11 +751,13 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
738 751
 						pv_value_destroy(&pval);
739 752
 						goto rv_str;
740 753
 					}else{
754
+						/* no PV_VAL_STR and no PV_VAL_INT => undef
755
+						   (PV_VAL_NULL) */
741 756
 						pv_value_destroy(&pval);
742
-						goto error;
757
+						goto undef;
743 758
 					}
744 759
 				}else{
745
-					goto error;
760
+					goto eval_error;
746 761
 				}
747 762
 			}
748 763
 			break;
... ...
@@ -751,10 +766,19 @@ int rval_get_int(struct run_act_ctx* h, struct sip_msg* msg,
751 766
 			goto error;
752 767
 	}
753 768
 	return 0;
769
+undef:
770
+eval_error: /* same as undefined */
771
+	/* handle undefined => result 0, return success */
772
+	*i=0;
773
+	return 0;
774
+error_cache:
775
+	BUG("invalid cached value:cache type %d, value type %d\n",
776
+			cache?cache->cache_type:0, cache?cache->val_type:0);
754 777
 rv_str:
755 778
 	/* rv is of string type => error */
756 779
 	/* ERR("string in int expression\n"); */
757 780
 error:
781
+	*i=0;
758 782
 	return -1;
759 783
 }
760 784
 
... ...
@@ -762,6 +786,9 @@ error:
762 786
 
763 787
 /** get the string value of an rv in a tmp variable
764 788
   * *s=(str)rv
789
+  * if rv == undefined select, avp or pvar, return "".
790
+  * if an error occurs while evaluating a select, avp or pvar, behave as
791
+  * for the undefined case (and return success).
765 792
   * The result points either to a temporary string or inside
766 793
   * new_cache. new_cache must be non zero, initialized previously,
767 794
   * and it _must_ be rval_cache_clean(...)'ed when done.
... ...
@@ -771,9 +798,9 @@ error:
771 798
   * @param h - script context handle
772 799
   * @param msg - sip msg
773 800
   * @param tmpv - str return value (pointer to a str struct that will be
774
-  *               be filled.
801
+  *               be filled with the conversion result)
775 802
   * @param rv   - rvalue to be converted
776
-  * @param cache - cached rv value (read-only)
803
+  * @param cache - cached rv value (read-only), can be 0
777 804
   * @param tmp_cache - used for temporary storage (so that tmpv will not
778 805
   *                 point to possible freed data), it must be non-null,
779 806
   *                 initialized and cleaned afterwards.
... ...
@@ -814,10 +841,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
814 841
 			i=run_select(tmpv, &rv->v.sel, msg);
815 842
 			if (unlikely(i!=0)){
816 843
 				if (i<0){
817
-					goto error;
818
-				}else { /* i>0 */
819
-					tmpv->s="";
820
-					tmpv->len=0;
844
+					goto eval_error;
845
+				}else { /* i>0  => undefined */
846
+					goto undef;
821 847
 				}
822 848
 			}
823 849
 			break;
... ...
@@ -828,7 +854,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
828 854
 				}else if (cache->val_type==RV_INT){
829 855
 					i=cache->c.avp_val.n;
830 856
 					tmpv->s=int2str(i, &tmpv->len);
831
-				}else goto error;
857
+				}else if (cache->val_type==RV_NONE){
858
+					goto undef;
859
+				}else goto error_cache;
832 860
 			}else{
833 861
 				r_avp = search_avp_by_index(rv->v.avps.type, rv->v.avps.name,
834 862
 											&tmp_cache->c.avp_val,
... ...
@@ -842,9 +870,7 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
842 870
 						i=tmp_cache->c.avp_val.n;
843 871
 						tmpv->s=int2str(i, &tmpv->len);
844 872
 					}
845
-				}else{
846
-					goto error;
847
-				}
873
+				}else goto undef;
848 874
 			}
849 875
 			break;
850 876
 		case RV_PVAR:
... ...
@@ -854,7 +880,9 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
854 880
 				}else if (cache->val_type==RV_INT){
855 881
 					i=cache->c.pval.ri;
856 882
 					tmpv->s=int2str(i, &tmpv->len);
857
-				}else goto error;
883
+				}else if (cache->val_type==RV_NONE){
884
+					goto undef;
885
+				}else goto error_cache;
858 886
 			}else{
859 887
 				memset(&tmp_cache->c.pval, 0, sizeof(tmp_cache->c.pval));
860 888
 				if (likely(pv_get_spec_value(msg, &rv->v.pvs,
... ...
@@ -871,11 +899,13 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
871 899
 						pv_value_destroy(&tmp_cache->c.pval);
872 900
 						tmpv->s=int2str(i, &tmpv->len);
873 901
 					}else{
902
+						/* no PV_VAL_STR and no PV_VAL_INT => undef
903
+						   (PV_VAL_NULL) */
874 904
 						pv_value_destroy(&tmp_cache->c.pval);
875
-						goto error;
905
+						goto undef;
876 906
 					}
877 907
 				}else{
878
-					goto error;
908
+					goto eval_error;
879 909
 				}
880 910
 			}
881 911
 			break;
... ...
@@ -884,7 +914,18 @@ int rval_get_tmp_str(struct run_act_ctx* h, struct sip_msg* msg,
884 914
 			goto error;
885 915
 	}
886 916
 	return 0;
917
+undef:
918
+eval_error: /* same as undefined */
919
+	/* handle undefined => result "", return success */
920
+	tmpv->s="";
921
+	tmpv->len=0;
922
+	return 0;
923
+error_cache:
924
+	BUG("invalid cached value:cache type %d, value type %d\n",
925
+			cache?cache->cache_type:0, cache?cache->val_type:0);
887 926
 error:
927
+	tmpv->s="";
928
+	tmpv->len=0;
888 929
 	return -1;
889 930
 }
890 931