/* Copyright (c) 2020 Contrast Security, Inc. See * https://www.contrastsecurity.com/enduser-terms-0317a for more details. */ #include "cs__assess_hash.h" #include "../cs__common/cs__common.h" #include static VALUE contrast_assess_hash_bracket_get(const int argc, VALUE *argv, const VALUE hash) { VALUE result; /* Array of Arrays: Hash[ [ [key, value], ... ] ] -> new_hash */ if (RB_TYPE_P(argv[0], T_ARRAY)) { int i; for (i = 0; i < argc; i++) { argv[i] = rb_funcall(hash, rb_sym_assess_hash_dup_and_freeze, 1, argv[i]); } /* Hash[ key, value, ... ] -> new_hash */ } else if (argc > 1) { int i; for (i = 0; i < argc; i += 2) { argv[i] = rb_funcall(hash, rb_sym_assess_hash_dup_and_freeze, 1, argv[i]); } } /* unhandled case - shouldn't need it since issue is only unfrozen * String keys * # Hash[ object ] -> new_hash */ result = rb_funcall2(hash, rb_sym_assess_hash_brackets, argc, argv); return result; } static VALUE contrast_assess_hash_bracket_set(const int argc, VALUE *argv, const VALUE hash) { VALUE result; VALUE key; key = rb_funcall2(hash, rb_sym_assess_hash_bracket_set, argc, argv); argv[0] = key; result = rb_funcall2(hash, rb_sym_assess_hash_bracket_equals, argc, argv); return result; } void Init_cs__assess_hash(void) { rb_sym_assess_hash_dup_and_freeze = rb_intern("cs__duplicate_and_freeze"); rb_sym_assess_hash_brackets = rb_intern("cs__patched_[]"); rb_sym_assess_hash_bracket_set = rb_intern("cs__bracket_set"); rb_sym_assess_hash_bracket_equals = rb_intern("cs__patched_[]="); VALUE hash_class = rb_define_class("Hash", rb_cObject); array_class = rb_define_class("Array", rb_cObject); VALUE singleton = rb_singleton_class(hash_class); contrast_alias_method(singleton, "cs__patched_[]", "[]"); rb_define_method(singleton, "[]", contrast_assess_hash_bracket_get, -1); contrast_alias_method(hash_class, "cs__patched_[]=", "[]="); rb_define_method(hash_class, "[]=", contrast_assess_hash_bracket_set, -1); }