From 5c854f6c5a7c0d1f562f34316f7c93e8ccbecc01 Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Mon, 21 Jan 2019 04:55:02 +0000 Subject: [PATCH 01/33] Bug 1516513 - Part 1. Add linux/aarch64 config to libvpx. r=jya To use NEON on Linux/aarch64 and Android/aarch64, I would like to add it to libvpx. libvpx has a configuration as arm64-linux-gcc. Differential Revision: https://phabricator.services.mozilla.com/D15400 --HG-- extra : moz-landing-system : lando --- media/libvpx/generate_sources_mozbuild.sh | 9 +++++++++ media/libvpx/moz.build | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/media/libvpx/generate_sources_mozbuild.sh b/media/libvpx/generate_sources_mozbuild.sh index 3ed282e2a5a1..e4eeca474bb9 100755 --- a/media/libvpx/generate_sources_mozbuild.sh +++ b/media/libvpx/generate_sources_mozbuild.sh @@ -199,6 +199,7 @@ all_platforms="${all_platforms} --enable-multi-res-encoding --size-limit=8192x46 all_platforms="${all_platforms} --disable-avx512" x86_platforms="--enable-postproc --enable-vp9-postproc --as=yasm" arm_platforms="--enable-runtime-cpu-detect --enable-realtime-only" +arm64_platforms="--enable-realtime-only" gen_config_files linux/x64 "--target=x86_64-linux-gcc ${all_platforms} ${x86_platforms}" gen_config_files linux/ia32 "--target=x86-linux-gcc ${all_platforms} ${x86_platforms}" @@ -210,6 +211,7 @@ gen_config_files win/mingw32 "--target=x86-win32-gcc ${all_platforms} ${x86_plat gen_config_files win/aarch64 "--target=aarch64-win64-vs12 ${all_platforms}" gen_config_files linux/arm "--target=armv7-linux-gcc ${all_platforms} ${arm_platforms}" +gen_config_files linux/arm64 "--target=arm64-linux-gcc ${all_platforms} ${arm64_platforms}" gen_config_files generic "--target=generic-gnu ${all_platforms}" @@ -238,6 +240,7 @@ gen_rtcd_header win/aarch64 aarch64 gen_rtcd_header linux/arm armv7 +gen_rtcd_header linux/arm64 arm64 gen_rtcd_header generic generic @@ -271,6 +274,12 @@ make_clean make libvpx_srcs.txt target=libs $config > /dev/null convert_srcs_to_project_files libvpx_srcs.txt ARM +echo "Generate ARM64 source list." +config=$(print_config linux/arm64) +make_clean +make libvpx_srcs.txt target=libs $config > /dev/null +convert_srcs_to_project_files libvpx_srcs.txt ARM64 + echo "Generate generic source list." config=$(print_config generic) make_clean diff --git a/media/libvpx/moz.build b/media/libvpx/moz.build index f445533155f7..c9d0a3b8c31a 100644 --- a/media/libvpx/moz.build +++ b/media/libvpx/moz.build @@ -81,6 +81,11 @@ elif CONFIG['CPU_ARCH'] == 'aarch64' and CONFIG['OS_TARGET'] == 'WINNT': SOURCES += files['GENERIC_SOURCES'] ASFLAGS += [ '-I%s/media/libvpx/config/win/aarch64/' % TOPSRCDIR ] LOCAL_INCLUDES += [ '/media/libvpx/config/win/aarch64/' ] +elif CONFIG['CPU_ARCH'] == 'aarch64': + EXPORTS.vpx += files['ARM64_EXPORTS'] + SOURCES += files['ARM64_SOURCES'] + ASFLAGS += [ '-I%s/media/libvpx/config/linux/arm64/' % TOPSRCDIR ] + LOCAL_INCLUDES += [ '/media/libvpx/config/linux/arm64/' ] else: # Generic C-only configuration EXPORTS.vpx += files['GENERIC_EXPORTS'] From a2a77288af9e11acfe21bd33679512e88afca5ec Mon Sep 17 00:00:00 2001 From: Makoto Kato Date: Mon, 21 Jan 2019 04:52:45 +0000 Subject: [PATCH 02/33] Bug 1516513 - Part 2. Add generated files to libvpx. r=jya Depends on D15400 Differential Revision: https://phabricator.services.mozilla.com/D15401 --HG-- extra : moz-landing-system : lando --- media/libvpx/config/linux/arm64/vp8_rtcd.h | 201 ++++ media/libvpx/config/linux/arm64/vp9_rtcd.h | 102 +++ .../libvpx/config/linux/arm64/vpx_config.asm | 86 ++ media/libvpx/config/linux/arm64/vpx_config.c | 10 + media/libvpx/config/linux/arm64/vpx_config.h | 97 ++ .../libvpx/config/linux/arm64/vpx_dsp_rtcd.h | 865 ++++++++++++++++++ .../config/linux/arm64/vpx_scale_rtcd.h | 75 ++ media/libvpx/sources.mozbuild | 229 +++++ 8 files changed, 1665 insertions(+) create mode 100644 media/libvpx/config/linux/arm64/vp8_rtcd.h create mode 100644 media/libvpx/config/linux/arm64/vp9_rtcd.h create mode 100644 media/libvpx/config/linux/arm64/vpx_config.asm create mode 100644 media/libvpx/config/linux/arm64/vpx_config.c create mode 100644 media/libvpx/config/linux/arm64/vpx_config.h create mode 100644 media/libvpx/config/linux/arm64/vpx_dsp_rtcd.h create mode 100644 media/libvpx/config/linux/arm64/vpx_scale_rtcd.h diff --git a/media/libvpx/config/linux/arm64/vp8_rtcd.h b/media/libvpx/config/linux/arm64/vp8_rtcd.h new file mode 100644 index 000000000000..4eb59c663009 --- /dev/null +++ b/media/libvpx/config/linux/arm64/vp8_rtcd.h @@ -0,0 +1,201 @@ +// This file is generated. Do not edit. +#ifndef VP8_RTCD_H_ +#define VP8_RTCD_H_ + +#ifdef RTCD_C +#define RTCD_EXTERN +#else +#define RTCD_EXTERN extern +#endif + +/* + * VP8 + */ + +struct blockd; +struct macroblockd; +struct loop_filter_info; + +/* Encoder forward decls */ +struct block; +struct macroblock; +struct variance_vtable; +union int_mv; +struct yv12_buffer_config; + +#ifdef __cplusplus +extern "C" { +#endif + +void vp8_bilinear_predict16x16_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_bilinear_predict16x16_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_bilinear_predict16x16 vp8_bilinear_predict16x16_neon + +void vp8_bilinear_predict4x4_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_bilinear_predict4x4_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_bilinear_predict4x4 vp8_bilinear_predict4x4_neon + +void vp8_bilinear_predict8x4_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_bilinear_predict8x4_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_bilinear_predict8x4 vp8_bilinear_predict8x4_neon + +void vp8_bilinear_predict8x8_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_bilinear_predict8x8_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_bilinear_predict8x8 vp8_bilinear_predict8x8_neon + +int vp8_block_error_c(short *coeff, short *dqcoeff); +#define vp8_block_error vp8_block_error_c + +void vp8_copy_mem16x16_c(unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch); +void vp8_copy_mem16x16_neon(unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch); +#define vp8_copy_mem16x16 vp8_copy_mem16x16_neon + +void vp8_copy_mem8x4_c(unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch); +void vp8_copy_mem8x4_neon(unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch); +#define vp8_copy_mem8x4 vp8_copy_mem8x4_neon + +void vp8_copy_mem8x8_c(unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch); +void vp8_copy_mem8x8_neon(unsigned char *src, int src_pitch, unsigned char *dst, int dst_pitch); +#define vp8_copy_mem8x8 vp8_copy_mem8x8_neon + +void vp8_dc_only_idct_add_c(short input, unsigned char *pred, int pred_stride, unsigned char *dst, int dst_stride); +void vp8_dc_only_idct_add_neon(short input, unsigned char *pred, int pred_stride, unsigned char *dst, int dst_stride); +#define vp8_dc_only_idct_add vp8_dc_only_idct_add_neon + +int vp8_denoiser_filter_c(unsigned char *mc_running_avg_y, int mc_avg_y_stride, unsigned char *running_avg_y, int avg_y_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude, int increase_denoising); +int vp8_denoiser_filter_neon(unsigned char *mc_running_avg_y, int mc_avg_y_stride, unsigned char *running_avg_y, int avg_y_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude, int increase_denoising); +#define vp8_denoiser_filter vp8_denoiser_filter_neon + +int vp8_denoiser_filter_uv_c(unsigned char *mc_running_avg, int mc_avg_stride, unsigned char *running_avg, int avg_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude, int increase_denoising); +int vp8_denoiser_filter_uv_neon(unsigned char *mc_running_avg, int mc_avg_stride, unsigned char *running_avg, int avg_stride, unsigned char *sig, int sig_stride, unsigned int motion_magnitude, int increase_denoising); +#define vp8_denoiser_filter_uv vp8_denoiser_filter_uv_neon + +void vp8_dequant_idct_add_c(short *input, short *dq, unsigned char *output, int stride); +void vp8_dequant_idct_add_neon(short *input, short *dq, unsigned char *output, int stride); +#define vp8_dequant_idct_add vp8_dequant_idct_add_neon + +void vp8_dequant_idct_add_uv_block_c(short *q, short *dq, unsigned char *dst_u, unsigned char *dst_v, int stride, char *eobs); +void vp8_dequant_idct_add_uv_block_neon(short *q, short *dq, unsigned char *dst_u, unsigned char *dst_v, int stride, char *eobs); +#define vp8_dequant_idct_add_uv_block vp8_dequant_idct_add_uv_block_neon + +void vp8_dequant_idct_add_y_block_c(short *q, short *dq, unsigned char *dst, int stride, char *eobs); +void vp8_dequant_idct_add_y_block_neon(short *q, short *dq, unsigned char *dst, int stride, char *eobs); +#define vp8_dequant_idct_add_y_block vp8_dequant_idct_add_y_block_neon + +void vp8_dequantize_b_c(struct blockd*, short *dqc); +void vp8_dequantize_b_neon(struct blockd*, short *dqc); +#define vp8_dequantize_b vp8_dequantize_b_neon + +int vp8_diamond_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, union int_mv *best_mv, int search_param, int sad_per_bit, int *num00, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); +#define vp8_diamond_search_sad vp8_diamond_search_sad_c + +void vp8_fast_quantize_b_c(struct block *, struct blockd *); +void vp8_fast_quantize_b_neon(struct block *, struct blockd *); +#define vp8_fast_quantize_b vp8_fast_quantize_b_neon + +int vp8_full_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); +#define vp8_full_search_sad vp8_full_search_sad_c + +void vp8_loop_filter_bh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +void vp8_loop_filter_bh_neon(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +#define vp8_loop_filter_bh vp8_loop_filter_bh_neon + +void vp8_loop_filter_bv_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +void vp8_loop_filter_bv_neon(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +#define vp8_loop_filter_bv vp8_loop_filter_bv_neon + +void vp8_loop_filter_mbh_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +void vp8_loop_filter_mbh_neon(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +#define vp8_loop_filter_mbh vp8_loop_filter_mbh_neon + +void vp8_loop_filter_mbv_c(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +void vp8_loop_filter_mbv_neon(unsigned char *y, unsigned char *u, unsigned char *v, int ystride, int uv_stride, struct loop_filter_info *lfi); +#define vp8_loop_filter_mbv vp8_loop_filter_mbv_neon + +void vp8_loop_filter_bhs_c(unsigned char *y, int ystride, const unsigned char *blimit); +void vp8_loop_filter_bhs_neon(unsigned char *y, int ystride, const unsigned char *blimit); +#define vp8_loop_filter_simple_bh vp8_loop_filter_bhs_neon + +void vp8_loop_filter_bvs_c(unsigned char *y, int ystride, const unsigned char *blimit); +void vp8_loop_filter_bvs_neon(unsigned char *y, int ystride, const unsigned char *blimit); +#define vp8_loop_filter_simple_bv vp8_loop_filter_bvs_neon + +void vp8_loop_filter_simple_horizontal_edge_c(unsigned char *y, int ystride, const unsigned char *blimit); +void vp8_loop_filter_mbhs_neon(unsigned char *y, int ystride, const unsigned char *blimit); +#define vp8_loop_filter_simple_mbh vp8_loop_filter_mbhs_neon + +void vp8_loop_filter_simple_vertical_edge_c(unsigned char *y, int ystride, const unsigned char *blimit); +void vp8_loop_filter_mbvs_neon(unsigned char *y, int ystride, const unsigned char *blimit); +#define vp8_loop_filter_simple_mbv vp8_loop_filter_mbvs_neon + +int vp8_mbblock_error_c(struct macroblock *mb, int dc); +#define vp8_mbblock_error vp8_mbblock_error_c + +int vp8_mbuverror_c(struct macroblock *mb); +#define vp8_mbuverror vp8_mbuverror_c + +int vp8_refining_search_sad_c(struct macroblock *x, struct block *b, struct blockd *d, union int_mv *ref_mv, int sad_per_bit, int distance, struct variance_vtable *fn_ptr, int *mvcost[2], union int_mv *center_mv); +#define vp8_refining_search_sad vp8_refining_search_sad_c + +void vp8_regular_quantize_b_c(struct block *, struct blockd *); +#define vp8_regular_quantize_b vp8_regular_quantize_b_c + +void vp8_short_fdct4x4_c(short *input, short *output, int pitch); +void vp8_short_fdct4x4_neon(short *input, short *output, int pitch); +#define vp8_short_fdct4x4 vp8_short_fdct4x4_neon + +void vp8_short_fdct8x4_c(short *input, short *output, int pitch); +void vp8_short_fdct8x4_neon(short *input, short *output, int pitch); +#define vp8_short_fdct8x4 vp8_short_fdct8x4_neon + +void vp8_short_idct4x4llm_c(short *input, unsigned char *pred, int pitch, unsigned char *dst, int dst_stride); +void vp8_short_idct4x4llm_neon(short *input, unsigned char *pred, int pitch, unsigned char *dst, int dst_stride); +#define vp8_short_idct4x4llm vp8_short_idct4x4llm_neon + +void vp8_short_inv_walsh4x4_c(short *input, short *output); +void vp8_short_inv_walsh4x4_neon(short *input, short *output); +#define vp8_short_inv_walsh4x4 vp8_short_inv_walsh4x4_neon + +void vp8_short_inv_walsh4x4_1_c(short *input, short *output); +#define vp8_short_inv_walsh4x4_1 vp8_short_inv_walsh4x4_1_c + +void vp8_short_walsh4x4_c(short *input, short *output, int pitch); +void vp8_short_walsh4x4_neon(short *input, short *output, int pitch); +#define vp8_short_walsh4x4 vp8_short_walsh4x4_neon + +void vp8_sixtap_predict16x16_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_sixtap_predict16x16_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_sixtap_predict16x16 vp8_sixtap_predict16x16_neon + +void vp8_sixtap_predict4x4_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_sixtap_predict4x4_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_sixtap_predict4x4 vp8_sixtap_predict4x4_neon + +void vp8_sixtap_predict8x4_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_sixtap_predict8x4_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_sixtap_predict8x4 vp8_sixtap_predict8x4_neon + +void vp8_sixtap_predict8x8_c(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +void vp8_sixtap_predict8x8_neon(unsigned char *src, int src_pitch, int xofst, int yofst, unsigned char *dst, int dst_pitch); +#define vp8_sixtap_predict8x8 vp8_sixtap_predict8x8_neon + +void vp8_rtcd(void); + +#include "vpx_config.h" + +#ifdef RTCD_C +#include "vpx_ports/arm.h" +static void setup_rtcd_internal(void) +{ + int flags = arm_cpu_caps(); + + (void)flags; + +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/media/libvpx/config/linux/arm64/vp9_rtcd.h b/media/libvpx/config/linux/arm64/vp9_rtcd.h new file mode 100644 index 000000000000..87a4961057bc --- /dev/null +++ b/media/libvpx/config/linux/arm64/vp9_rtcd.h @@ -0,0 +1,102 @@ +// This file is generated. Do not edit. +#ifndef VP9_RTCD_H_ +#define VP9_RTCD_H_ + +#ifdef RTCD_C +#define RTCD_EXTERN +#else +#define RTCD_EXTERN extern +#endif + +/* + * VP9 + */ + +#include "vpx/vpx_integer.h" +#include "vp9/common/vp9_common.h" +#include "vp9/common/vp9_enums.h" +#include "vp9/common/vp9_filter.h" + +struct macroblockd; + +/* Encoder forward decls */ +struct macroblock; +struct vp9_variance_vtable; +struct search_site_config; +struct mv; +union int_mv; +struct yv12_buffer_config; + +#ifdef __cplusplus +extern "C" { +#endif + +int64_t vp9_block_error_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, intptr_t block_size, int64_t *ssz); +#define vp9_block_error vp9_block_error_c + +int64_t vp9_block_error_fp_c(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); +int64_t vp9_block_error_fp_neon(const tran_low_t *coeff, const tran_low_t *dqcoeff, int block_size); +#define vp9_block_error_fp vp9_block_error_fp_neon + +int vp9_diamond_search_sad_c(const struct macroblock *x, const struct search_site_config *cfg, struct mv *ref_mv, struct mv *best_mv, int search_param, int sad_per_bit, int *num00, const struct vp9_variance_vtable *fn_ptr, const struct mv *center_mv); +#define vp9_diamond_search_sad vp9_diamond_search_sad_c + +void vp9_fdct8x8_quant_c(const int16_t *input, int stride, tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *round_ptr, const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vp9_fdct8x8_quant_neon(const int16_t *input, int stride, tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *round_ptr, const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +#define vp9_fdct8x8_quant vp9_fdct8x8_quant_neon + +void vp9_fht16x16_c(const int16_t *input, tran_low_t *output, int stride, int tx_type); +#define vp9_fht16x16 vp9_fht16x16_c + +void vp9_fht4x4_c(const int16_t *input, tran_low_t *output, int stride, int tx_type); +#define vp9_fht4x4 vp9_fht4x4_c + +void vp9_fht8x8_c(const int16_t *input, tran_low_t *output, int stride, int tx_type); +#define vp9_fht8x8 vp9_fht8x8_c + +void vp9_fwht4x4_c(const int16_t *input, tran_low_t *output, int stride); +#define vp9_fwht4x4 vp9_fwht4x4_c + +void vp9_iht16x16_256_add_c(const tran_low_t *input, uint8_t *output, int pitch, int tx_type); +#define vp9_iht16x16_256_add vp9_iht16x16_256_add_c + +void vp9_iht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); +void vp9_iht4x4_16_add_neon(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); +#define vp9_iht4x4_16_add vp9_iht4x4_16_add_neon + +void vp9_iht8x8_64_add_c(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); +void vp9_iht8x8_64_add_neon(const tran_low_t *input, uint8_t *dest, int stride, int tx_type); +#define vp9_iht8x8_64_add vp9_iht8x8_64_add_neon + +void vp9_quantize_fp_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *round_ptr, const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vp9_quantize_fp_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *round_ptr, const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +#define vp9_quantize_fp vp9_quantize_fp_neon + +void vp9_quantize_fp_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *round_ptr, const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vp9_quantize_fp_32x32_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *round_ptr, const int16_t *quant_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +#define vp9_quantize_fp_32x32 vp9_quantize_fp_32x32_neon + +void vp9_scale_and_extend_frame_c(const struct yv12_buffer_config *src, struct yv12_buffer_config *dst, INTERP_FILTER filter_type, int phase_scaler); +void vp9_scale_and_extend_frame_neon(const struct yv12_buffer_config *src, struct yv12_buffer_config *dst, INTERP_FILTER filter_type, int phase_scaler); +#define vp9_scale_and_extend_frame vp9_scale_and_extend_frame_neon + +void vp9_rtcd(void); + +#include "vpx_config.h" + +#ifdef RTCD_C +#include "vpx_ports/arm.h" +static void setup_rtcd_internal(void) +{ + int flags = arm_cpu_caps(); + + (void)flags; + +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/media/libvpx/config/linux/arm64/vpx_config.asm b/media/libvpx/config/linux/arm64/vpx_config.asm new file mode 100644 index 000000000000..983d0c4e6e21 --- /dev/null +++ b/media/libvpx/config/linux/arm64/vpx_config.asm @@ -0,0 +1,86 @@ +@ This file was created from a .asm file +@ using the ads2gas.pl script. + .equ DO1STROUNDING, 0 +.equ ARCH_ARM , 1 +.equ ARCH_MIPS , 0 +.equ ARCH_X86 , 0 +.equ ARCH_X86_64 , 0 +.equ ARCH_PPC , 0 +.equ HAVE_NEON , 1 +.equ HAVE_NEON_ASM , 0 +.equ HAVE_MIPS32 , 0 +.equ HAVE_DSPR2 , 0 +.equ HAVE_MSA , 0 +.equ HAVE_MIPS64 , 0 +.equ HAVE_MMX , 0 +.equ HAVE_SSE , 0 +.equ HAVE_SSE2 , 0 +.equ HAVE_SSE3 , 0 +.equ HAVE_SSSE3 , 0 +.equ HAVE_SSE4_1 , 0 +.equ HAVE_AVX , 0 +.equ HAVE_AVX2 , 0 +.equ HAVE_AVX512 , 0 +.equ HAVE_VSX , 0 +.equ HAVE_MMI , 0 +.equ HAVE_VPX_PORTS , 1 +.equ HAVE_PTHREAD_H , 1 +.equ CONFIG_DEPENDENCY_TRACKING , 1 +.equ CONFIG_EXTERNAL_BUILD , 1 +.equ CONFIG_INSTALL_DOCS , 0 +.equ CONFIG_INSTALL_BINS , 1 +.equ CONFIG_INSTALL_LIBS , 1 +.equ CONFIG_INSTALL_SRCS , 0 +.equ CONFIG_DEBUG , 0 +.equ CONFIG_GPROF , 0 +.equ CONFIG_GCOV , 0 +.equ CONFIG_RVCT , 0 +.equ CONFIG_GCC , 1 +.equ CONFIG_MSVS , 0 +.equ CONFIG_PIC , 1 +.equ CONFIG_BIG_ENDIAN , 0 +.equ CONFIG_CODEC_SRCS , 0 +.equ CONFIG_DEBUG_LIBS , 0 +.equ CONFIG_DEQUANT_TOKENS , 0 +.equ CONFIG_DC_RECON , 0 +.equ CONFIG_RUNTIME_CPU_DETECT , 0 +.equ CONFIG_POSTPROC , 0 +.equ CONFIG_VP9_POSTPROC , 0 +.equ CONFIG_MULTITHREAD , 1 +.equ CONFIG_INTERNAL_STATS , 0 +.equ CONFIG_VP8_ENCODER , 1 +.equ CONFIG_VP8_DECODER , 1 +.equ CONFIG_VP9_ENCODER , 1 +.equ CONFIG_VP9_DECODER , 1 +.equ CONFIG_VP8 , 1 +.equ CONFIG_VP9 , 1 +.equ CONFIG_ENCODERS , 1 +.equ CONFIG_DECODERS , 1 +.equ CONFIG_STATIC_MSVCRT , 0 +.equ CONFIG_SPATIAL_RESAMPLING , 1 +.equ CONFIG_REALTIME_ONLY , 1 +.equ CONFIG_ONTHEFLY_BITPACKING , 0 +.equ CONFIG_ERROR_CONCEALMENT , 0 +.equ CONFIG_SHARED , 0 +.equ CONFIG_STATIC , 1 +.equ CONFIG_SMALL , 0 +.equ CONFIG_POSTPROC_VISUALIZER , 0 +.equ CONFIG_OS_SUPPORT , 1 +.equ CONFIG_UNIT_TESTS , 0 +.equ CONFIG_WEBM_IO , 1 +.equ CONFIG_LIBYUV , 1 +.equ CONFIG_DECODE_PERF_TESTS , 0 +.equ CONFIG_ENCODE_PERF_TESTS , 0 +.equ CONFIG_MULTI_RES_ENCODING , 1 +.equ CONFIG_TEMPORAL_DENOISING , 1 +.equ CONFIG_VP9_TEMPORAL_DENOISING , 0 +.equ CONFIG_COEFFICIENT_RANGE_CHECKING , 0 +.equ CONFIG_VP9_HIGHBITDEPTH , 0 +.equ CONFIG_BETTER_HW_COMPATIBILITY , 0 +.equ CONFIG_EXPERIMENTAL , 0 +.equ CONFIG_SIZE_LIMIT , 1 +.equ CONFIG_ALWAYS_ADJUST_BPM , 0 +.equ CONFIG_SPATIAL_SVC , 0 +.equ CONFIG_FP_MB_STATS , 0 +.equ CONFIG_EMULATE_HARDWARE , 0 + .section .note.GNU-stack,"",%progbits diff --git a/media/libvpx/config/linux/arm64/vpx_config.c b/media/libvpx/config/linux/arm64/vpx_config.c new file mode 100644 index 000000000000..74baa0689cb3 --- /dev/null +++ b/media/libvpx/config/linux/arm64/vpx_config.c @@ -0,0 +1,10 @@ +/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */ +/* */ +/* Use of this source code is governed by a BSD-style license */ +/* that can be found in the LICENSE file in the root of the source */ +/* tree. An additional intellectual property rights grant can be found */ +/* in the file PATENTS. All contributing project authors may */ +/* be found in the AUTHORS file in the root of the source tree. */ +#include "vpx/vpx_codec.h" +static const char* const cfg = "--target=arm64-linux-gcc --enable-external-build --disable-examples --disable-install-docs --disable-unit-tests --enable-multi-res-encoding --size-limit=8192x4608 --enable-pic --disable-avx512 --enable-realtime-only"; +const char *vpx_codec_build_config(void) {return cfg;} diff --git a/media/libvpx/config/linux/arm64/vpx_config.h b/media/libvpx/config/linux/arm64/vpx_config.h new file mode 100644 index 000000000000..80c0e97810ce --- /dev/null +++ b/media/libvpx/config/linux/arm64/vpx_config.h @@ -0,0 +1,97 @@ +/* Copyright (c) 2011 The WebM project authors. All Rights Reserved. */ +/* */ +/* Use of this source code is governed by a BSD-style license */ +/* that can be found in the LICENSE file in the root of the source */ +/* tree. An additional intellectual property rights grant can be found */ +/* in the file PATENTS. All contributing project authors may */ +/* be found in the AUTHORS file in the root of the source tree. */ +/* This file automatically generated by configure. Do not edit! */ +#ifndef VPX_CONFIG_H +#define VPX_CONFIG_H +#define RESTRICT +#define INLINE inline +#define ARCH_ARM 1 +#define ARCH_MIPS 0 +#define ARCH_X86 0 +#define ARCH_X86_64 0 +#define ARCH_PPC 0 +#define HAVE_NEON 1 +#define HAVE_NEON_ASM 0 +#define HAVE_MIPS32 0 +#define HAVE_DSPR2 0 +#define HAVE_MSA 0 +#define HAVE_MIPS64 0 +#define HAVE_MMX 0 +#define HAVE_SSE 0 +#define HAVE_SSE2 0 +#define HAVE_SSE3 0 +#define HAVE_SSSE3 0 +#define HAVE_SSE4_1 0 +#define HAVE_AVX 0 +#define HAVE_AVX2 0 +#define HAVE_AVX512 0 +#define HAVE_VSX 0 +#define HAVE_MMI 0 +#define HAVE_VPX_PORTS 1 +#define HAVE_PTHREAD_H 1 +#define CONFIG_DEPENDENCY_TRACKING 1 +#define CONFIG_EXTERNAL_BUILD 1 +#define CONFIG_INSTALL_DOCS 0 +#define CONFIG_INSTALL_BINS 1 +#define CONFIG_INSTALL_LIBS 1 +#define CONFIG_INSTALL_SRCS 0 +#define CONFIG_DEBUG 0 +#define CONFIG_GPROF 0 +#define CONFIG_GCOV 0 +#define CONFIG_RVCT 0 +#define CONFIG_GCC 1 +#define CONFIG_MSVS 0 +#define CONFIG_PIC 1 +#define CONFIG_BIG_ENDIAN 0 +#define CONFIG_CODEC_SRCS 0 +#define CONFIG_DEBUG_LIBS 0 +#define CONFIG_DEQUANT_TOKENS 0 +#define CONFIG_DC_RECON 0 +#define CONFIG_RUNTIME_CPU_DETECT 0 +#define CONFIG_POSTPROC 0 +#define CONFIG_VP9_POSTPROC 0 +#define CONFIG_MULTITHREAD 1 +#define CONFIG_INTERNAL_STATS 0 +#define CONFIG_VP8_ENCODER 1 +#define CONFIG_VP8_DECODER 1 +#define CONFIG_VP9_ENCODER 1 +#define CONFIG_VP9_DECODER 1 +#define CONFIG_VP8 1 +#define CONFIG_VP9 1 +#define CONFIG_ENCODERS 1 +#define CONFIG_DECODERS 1 +#define CONFIG_STATIC_MSVCRT 0 +#define CONFIG_SPATIAL_RESAMPLING 1 +#define CONFIG_REALTIME_ONLY 1 +#define CONFIG_ONTHEFLY_BITPACKING 0 +#define CONFIG_ERROR_CONCEALMENT 0 +#define CONFIG_SHARED 0 +#define CONFIG_STATIC 1 +#define CONFIG_SMALL 0 +#define CONFIG_POSTPROC_VISUALIZER 0 +#define CONFIG_OS_SUPPORT 1 +#define CONFIG_UNIT_TESTS 0 +#define CONFIG_WEBM_IO 1 +#define CONFIG_LIBYUV 1 +#define CONFIG_DECODE_PERF_TESTS 0 +#define CONFIG_ENCODE_PERF_TESTS 0 +#define CONFIG_MULTI_RES_ENCODING 1 +#define CONFIG_TEMPORAL_DENOISING 1 +#define CONFIG_VP9_TEMPORAL_DENOISING 0 +#define CONFIG_COEFFICIENT_RANGE_CHECKING 0 +#define CONFIG_VP9_HIGHBITDEPTH 0 +#define CONFIG_BETTER_HW_COMPATIBILITY 0 +#define CONFIG_EXPERIMENTAL 0 +#define CONFIG_SIZE_LIMIT 1 +#define CONFIG_ALWAYS_ADJUST_BPM 0 +#define CONFIG_SPATIAL_SVC 0 +#define CONFIG_FP_MB_STATS 0 +#define CONFIG_EMULATE_HARDWARE 0 +#define DECODE_WIDTH_LIMIT 8192 +#define DECODE_HEIGHT_LIMIT 4608 +#endif /* VPX_CONFIG_H */ diff --git a/media/libvpx/config/linux/arm64/vpx_dsp_rtcd.h b/media/libvpx/config/linux/arm64/vpx_dsp_rtcd.h new file mode 100644 index 000000000000..996ad070c8c6 --- /dev/null +++ b/media/libvpx/config/linux/arm64/vpx_dsp_rtcd.h @@ -0,0 +1,865 @@ +// This file is generated. Do not edit. +#ifndef VPX_DSP_RTCD_H_ +#define VPX_DSP_RTCD_H_ + +#ifdef RTCD_C +#define RTCD_EXTERN +#else +#define RTCD_EXTERN extern +#endif + +/* + * DSP + */ + +#include "vpx/vpx_integer.h" +#include "vpx_dsp/vpx_dsp_common.h" +#include "vpx_dsp/vpx_filter.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +unsigned int vpx_avg_4x4_c(const uint8_t *, int p); +unsigned int vpx_avg_4x4_neon(const uint8_t *, int p); +#define vpx_avg_4x4 vpx_avg_4x4_neon + +unsigned int vpx_avg_8x8_c(const uint8_t *, int p); +unsigned int vpx_avg_8x8_neon(const uint8_t *, int p); +#define vpx_avg_8x8 vpx_avg_8x8_neon + +void vpx_comp_avg_pred_c(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride); +void vpx_comp_avg_pred_neon(uint8_t *comp_pred, const uint8_t *pred, int width, int height, const uint8_t *ref, int ref_stride); +#define vpx_comp_avg_pred vpx_comp_avg_pred_neon + +void vpx_convolve8_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve8_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8 vpx_convolve8_neon + +void vpx_convolve8_avg_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve8_avg_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_avg vpx_convolve8_avg_neon + +void vpx_convolve8_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve8_avg_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_avg_horiz vpx_convolve8_avg_horiz_neon + +void vpx_convolve8_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve8_avg_vert_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_avg_vert vpx_convolve8_avg_vert_neon + +void vpx_convolve8_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve8_horiz_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_horiz vpx_convolve8_horiz_neon + +void vpx_convolve8_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve8_vert_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve8_vert vpx_convolve8_vert_neon + +void vpx_convolve_avg_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve_avg_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve_avg vpx_convolve_avg_neon + +void vpx_convolve_copy_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_convolve_copy_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_convolve_copy vpx_convolve_copy_neon + +void vpx_d117_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_16x16 vpx_d117_predictor_16x16_c + +void vpx_d117_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_32x32 vpx_d117_predictor_32x32_c + +void vpx_d117_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_4x4 vpx_d117_predictor_4x4_c + +void vpx_d117_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d117_predictor_8x8 vpx_d117_predictor_8x8_c + +void vpx_d135_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d135_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_16x16 vpx_d135_predictor_16x16_neon + +void vpx_d135_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d135_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_32x32 vpx_d135_predictor_32x32_neon + +void vpx_d135_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d135_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_4x4 vpx_d135_predictor_4x4_neon + +void vpx_d135_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d135_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d135_predictor_8x8 vpx_d135_predictor_8x8_neon + +void vpx_d153_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_16x16 vpx_d153_predictor_16x16_c + +void vpx_d153_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_32x32 vpx_d153_predictor_32x32_c + +void vpx_d153_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_4x4 vpx_d153_predictor_4x4_c + +void vpx_d153_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d153_predictor_8x8 vpx_d153_predictor_8x8_c + +void vpx_d207_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_16x16 vpx_d207_predictor_16x16_c + +void vpx_d207_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_32x32 vpx_d207_predictor_32x32_c + +void vpx_d207_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_4x4 vpx_d207_predictor_4x4_c + +void vpx_d207_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d207_predictor_8x8 vpx_d207_predictor_8x8_c + +void vpx_d45_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_16x16 vpx_d45_predictor_16x16_neon + +void vpx_d45_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_32x32 vpx_d45_predictor_32x32_neon + +void vpx_d45_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_4x4 vpx_d45_predictor_4x4_neon + +void vpx_d45_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_d45_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45_predictor_8x8 vpx_d45_predictor_8x8_neon + +void vpx_d45e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d45e_predictor_4x4 vpx_d45e_predictor_4x4_c + +void vpx_d63_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_16x16 vpx_d63_predictor_16x16_c + +void vpx_d63_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_32x32 vpx_d63_predictor_32x32_c + +void vpx_d63_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_4x4 vpx_d63_predictor_4x4_c + +void vpx_d63_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63_predictor_8x8 vpx_d63_predictor_8x8_c + +void vpx_d63e_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_d63e_predictor_4x4 vpx_d63e_predictor_4x4_c + +void vpx_dc_128_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_128_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_16x16 vpx_dc_128_predictor_16x16_neon + +void vpx_dc_128_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_128_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_32x32 vpx_dc_128_predictor_32x32_neon + +void vpx_dc_128_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_128_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_4x4 vpx_dc_128_predictor_4x4_neon + +void vpx_dc_128_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_128_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_128_predictor_8x8 vpx_dc_128_predictor_8x8_neon + +void vpx_dc_left_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_left_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_16x16 vpx_dc_left_predictor_16x16_neon + +void vpx_dc_left_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_left_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_32x32 vpx_dc_left_predictor_32x32_neon + +void vpx_dc_left_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_left_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_4x4 vpx_dc_left_predictor_4x4_neon + +void vpx_dc_left_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_left_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_left_predictor_8x8 vpx_dc_left_predictor_8x8_neon + +void vpx_dc_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_16x16 vpx_dc_predictor_16x16_neon + +void vpx_dc_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_32x32 vpx_dc_predictor_32x32_neon + +void vpx_dc_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_4x4 vpx_dc_predictor_4x4_neon + +void vpx_dc_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_predictor_8x8 vpx_dc_predictor_8x8_neon + +void vpx_dc_top_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_top_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_16x16 vpx_dc_top_predictor_16x16_neon + +void vpx_dc_top_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_top_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_32x32 vpx_dc_top_predictor_32x32_neon + +void vpx_dc_top_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_top_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_4x4 vpx_dc_top_predictor_4x4_neon + +void vpx_dc_top_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_dc_top_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_dc_top_predictor_8x8 vpx_dc_top_predictor_8x8_neon + +void vpx_fdct16x16_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct16x16_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct16x16 vpx_fdct16x16_neon + +void vpx_fdct16x16_1_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct16x16_1_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct16x16_1 vpx_fdct16x16_1_neon + +void vpx_fdct32x32_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct32x32_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct32x32 vpx_fdct32x32_neon + +void vpx_fdct32x32_1_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct32x32_1_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct32x32_1 vpx_fdct32x32_1_neon + +void vpx_fdct32x32_rd_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct32x32_rd_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct32x32_rd vpx_fdct32x32_rd_neon + +void vpx_fdct4x4_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct4x4_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct4x4 vpx_fdct4x4_neon + +void vpx_fdct4x4_1_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct4x4_1_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct4x4_1 vpx_fdct4x4_1_neon + +void vpx_fdct8x8_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct8x8_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct8x8 vpx_fdct8x8_neon + +void vpx_fdct8x8_1_c(const int16_t *input, tran_low_t *output, int stride); +void vpx_fdct8x8_1_neon(const int16_t *input, tran_low_t *output, int stride); +#define vpx_fdct8x8_1 vpx_fdct8x8_1_neon + +void vpx_get16x16var_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, int *sum); +void vpx_get16x16var_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, int *sum); +#define vpx_get16x16var vpx_get16x16var_neon + +unsigned int vpx_get4x4sse_cs_c(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride); +unsigned int vpx_get4x4sse_cs_neon(const unsigned char *src_ptr, int source_stride, const unsigned char *ref_ptr, int ref_stride); +#define vpx_get4x4sse_cs vpx_get4x4sse_cs_neon + +void vpx_get8x8var_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, int *sum); +void vpx_get8x8var_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse, int *sum); +#define vpx_get8x8var vpx_get8x8var_neon + +unsigned int vpx_get_mb_ss_c(const int16_t *); +#define vpx_get_mb_ss vpx_get_mb_ss_c + +void vpx_h_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_h_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_16x16 vpx_h_predictor_16x16_neon + +void vpx_h_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_h_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_32x32 vpx_h_predictor_32x32_neon + +void vpx_h_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_h_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_4x4 vpx_h_predictor_4x4_neon + +void vpx_h_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_h_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_h_predictor_8x8 vpx_h_predictor_8x8_neon + +void vpx_hadamard_16x16_c(const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff); +void vpx_hadamard_16x16_neon(const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff); +#define vpx_hadamard_16x16 vpx_hadamard_16x16_neon + +void vpx_hadamard_8x8_c(const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff); +void vpx_hadamard_8x8_neon(const int16_t *src_diff, ptrdiff_t src_stride, int16_t *coeff); +#define vpx_hadamard_8x8 vpx_hadamard_8x8_neon + +void vpx_he_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_he_predictor_4x4 vpx_he_predictor_4x4_c + +void vpx_idct16x16_10_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct16x16_10_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_10_add vpx_idct16x16_10_add_neon + +void vpx_idct16x16_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct16x16_1_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_1_add vpx_idct16x16_1_add_neon + +void vpx_idct16x16_256_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct16x16_256_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_256_add vpx_idct16x16_256_add_neon + +void vpx_idct16x16_38_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct16x16_38_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct16x16_38_add vpx_idct16x16_38_add_neon + +void vpx_idct32x32_1024_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct32x32_1024_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_1024_add vpx_idct32x32_1024_add_neon + +void vpx_idct32x32_135_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct32x32_135_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_135_add vpx_idct32x32_135_add_neon + +void vpx_idct32x32_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct32x32_1_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_1_add vpx_idct32x32_1_add_neon + +void vpx_idct32x32_34_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct32x32_34_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct32x32_34_add vpx_idct32x32_34_add_neon + +void vpx_idct4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct4x4_16_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct4x4_16_add vpx_idct4x4_16_add_neon + +void vpx_idct4x4_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct4x4_1_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct4x4_1_add vpx_idct4x4_1_add_neon + +void vpx_idct8x8_12_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct8x8_12_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct8x8_12_add vpx_idct8x8_12_add_neon + +void vpx_idct8x8_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct8x8_1_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct8x8_1_add vpx_idct8x8_1_add_neon + +void vpx_idct8x8_64_add_c(const tran_low_t *input, uint8_t *dest, int stride); +void vpx_idct8x8_64_add_neon(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_idct8x8_64_add vpx_idct8x8_64_add_neon + +int16_t vpx_int_pro_col_c(const uint8_t *ref, const int width); +int16_t vpx_int_pro_col_neon(const uint8_t *ref, const int width); +#define vpx_int_pro_col vpx_int_pro_col_neon + +void vpx_int_pro_row_c(int16_t *hbuf, const uint8_t *ref, const int ref_stride, const int height); +void vpx_int_pro_row_neon(int16_t *hbuf, const uint8_t *ref, const int ref_stride, const int height); +#define vpx_int_pro_row vpx_int_pro_row_neon + +void vpx_iwht4x4_16_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_iwht4x4_16_add vpx_iwht4x4_16_add_c + +void vpx_iwht4x4_1_add_c(const tran_low_t *input, uint8_t *dest, int stride); +#define vpx_iwht4x4_1_add vpx_iwht4x4_1_add_c + +void vpx_lpf_horizontal_16_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_horizontal_16_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_16 vpx_lpf_horizontal_16_neon + +void vpx_lpf_horizontal_16_dual_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_horizontal_16_dual_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_16_dual vpx_lpf_horizontal_16_dual_neon + +void vpx_lpf_horizontal_4_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_horizontal_4_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_4 vpx_lpf_horizontal_4_neon + +void vpx_lpf_horizontal_4_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +void vpx_lpf_horizontal_4_dual_neon(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_horizontal_4_dual vpx_lpf_horizontal_4_dual_neon + +void vpx_lpf_horizontal_8_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_horizontal_8_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_horizontal_8 vpx_lpf_horizontal_8_neon + +void vpx_lpf_horizontal_8_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +void vpx_lpf_horizontal_8_dual_neon(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_horizontal_8_dual vpx_lpf_horizontal_8_dual_neon + +void vpx_lpf_vertical_16_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_vertical_16_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_16 vpx_lpf_vertical_16_neon + +void vpx_lpf_vertical_16_dual_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_vertical_16_dual_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_16_dual vpx_lpf_vertical_16_dual_neon + +void vpx_lpf_vertical_4_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_vertical_4_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_4 vpx_lpf_vertical_4_neon + +void vpx_lpf_vertical_4_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +void vpx_lpf_vertical_4_dual_neon(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_vertical_4_dual vpx_lpf_vertical_4_dual_neon + +void vpx_lpf_vertical_8_c(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +void vpx_lpf_vertical_8_neon(uint8_t *s, int pitch, const uint8_t *blimit, const uint8_t *limit, const uint8_t *thresh); +#define vpx_lpf_vertical_8 vpx_lpf_vertical_8_neon + +void vpx_lpf_vertical_8_dual_c(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +void vpx_lpf_vertical_8_dual_neon(uint8_t *s, int pitch, const uint8_t *blimit0, const uint8_t *limit0, const uint8_t *thresh0, const uint8_t *blimit1, const uint8_t *limit1, const uint8_t *thresh1); +#define vpx_lpf_vertical_8_dual vpx_lpf_vertical_8_dual_neon + +void vpx_minmax_8x8_c(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max); +void vpx_minmax_8x8_neon(const uint8_t *s, int p, const uint8_t *d, int dp, int *min, int *max); +#define vpx_minmax_8x8 vpx_minmax_8x8_neon + +unsigned int vpx_mse16x16_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int recon_stride, unsigned int *sse); +unsigned int vpx_mse16x16_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int recon_stride, unsigned int *sse); +#define vpx_mse16x16 vpx_mse16x16_neon + +unsigned int vpx_mse16x8_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int recon_stride, unsigned int *sse); +#define vpx_mse16x8 vpx_mse16x8_c + +unsigned int vpx_mse8x16_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int recon_stride, unsigned int *sse); +#define vpx_mse8x16 vpx_mse8x16_c + +unsigned int vpx_mse8x8_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int recon_stride, unsigned int *sse); +#define vpx_mse8x8 vpx_mse8x8_c + +void vpx_quantize_b_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vpx_quantize_b_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +#define vpx_quantize_b vpx_quantize_b_neon + +void vpx_quantize_b_32x32_c(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +void vpx_quantize_b_32x32_neon(const tran_low_t *coeff_ptr, intptr_t n_coeffs, int skip_block, const int16_t *zbin_ptr, const int16_t *round_ptr, const int16_t *quant_ptr, const int16_t *quant_shift_ptr, tran_low_t *qcoeff_ptr, tran_low_t *dqcoeff_ptr, const int16_t *dequant_ptr, uint16_t *eob_ptr, const int16_t *scan, const int16_t *iscan); +#define vpx_quantize_b_32x32 vpx_quantize_b_32x32_neon + +unsigned int vpx_sad16x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad16x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad16x16 vpx_sad16x16_neon + +unsigned int vpx_sad16x16_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad16x16_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad16x16_avg vpx_sad16x16_avg_neon + +void vpx_sad16x16x3_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad16x16x3 vpx_sad16x16x3_c + +void vpx_sad16x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad16x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad16x16x4d vpx_sad16x16x4d_neon + +void vpx_sad16x16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad16x16x8 vpx_sad16x16x8_c + +unsigned int vpx_sad16x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad16x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad16x32 vpx_sad16x32_neon + +unsigned int vpx_sad16x32_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad16x32_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad16x32_avg vpx_sad16x32_avg_neon + +void vpx_sad16x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad16x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad16x32x4d vpx_sad16x32x4d_neon + +unsigned int vpx_sad16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad16x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad16x8 vpx_sad16x8_neon + +unsigned int vpx_sad16x8_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad16x8_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad16x8_avg vpx_sad16x8_avg_neon + +void vpx_sad16x8x3_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad16x8x3 vpx_sad16x8x3_c + +void vpx_sad16x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad16x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad16x8x4d vpx_sad16x8x4d_neon + +void vpx_sad16x8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad16x8x8 vpx_sad16x8x8_c + +unsigned int vpx_sad32x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad32x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad32x16 vpx_sad32x16_neon + +unsigned int vpx_sad32x16_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad32x16_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad32x16_avg vpx_sad32x16_avg_neon + +void vpx_sad32x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad32x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad32x16x4d vpx_sad32x16x4d_neon + +unsigned int vpx_sad32x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad32x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad32x32 vpx_sad32x32_neon + +unsigned int vpx_sad32x32_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad32x32_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad32x32_avg vpx_sad32x32_avg_neon + +void vpx_sad32x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad32x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad32x32x4d vpx_sad32x32x4d_neon + +unsigned int vpx_sad32x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad32x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad32x64 vpx_sad32x64_neon + +unsigned int vpx_sad32x64_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad32x64_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad32x64_avg vpx_sad32x64_avg_neon + +void vpx_sad32x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad32x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad32x64x4d vpx_sad32x64x4d_neon + +unsigned int vpx_sad4x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad4x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad4x4 vpx_sad4x4_neon + +unsigned int vpx_sad4x4_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad4x4_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad4x4_avg vpx_sad4x4_avg_neon + +void vpx_sad4x4x3_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad4x4x3 vpx_sad4x4x3_c + +void vpx_sad4x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad4x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad4x4x4d vpx_sad4x4x4d_neon + +void vpx_sad4x4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad4x4x8 vpx_sad4x4x8_c + +unsigned int vpx_sad4x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad4x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad4x8 vpx_sad4x8_neon + +unsigned int vpx_sad4x8_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad4x8_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad4x8_avg vpx_sad4x8_avg_neon + +void vpx_sad4x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad4x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad4x8x4d vpx_sad4x8x4d_neon + +unsigned int vpx_sad64x32_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad64x32_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad64x32 vpx_sad64x32_neon + +unsigned int vpx_sad64x32_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad64x32_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad64x32_avg vpx_sad64x32_avg_neon + +void vpx_sad64x32x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad64x32x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad64x32x4d vpx_sad64x32x4d_neon + +unsigned int vpx_sad64x64_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad64x64_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad64x64 vpx_sad64x64_neon + +unsigned int vpx_sad64x64_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad64x64_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad64x64_avg vpx_sad64x64_avg_neon + +void vpx_sad64x64x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad64x64x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad64x64x4d vpx_sad64x64x4d_neon + +unsigned int vpx_sad8x16_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad8x16_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad8x16 vpx_sad8x16_neon + +unsigned int vpx_sad8x16_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad8x16_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad8x16_avg vpx_sad8x16_avg_neon + +void vpx_sad8x16x3_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad8x16x3 vpx_sad8x16x3_c + +void vpx_sad8x16x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad8x16x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad8x16x4d vpx_sad8x16x4d_neon + +void vpx_sad8x16x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad8x16x8 vpx_sad8x16x8_c + +unsigned int vpx_sad8x4_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad8x4_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad8x4 vpx_sad8x4_neon + +unsigned int vpx_sad8x4_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad8x4_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad8x4_avg vpx_sad8x4_avg_neon + +void vpx_sad8x4x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad8x4x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad8x4x4d vpx_sad8x4x4d_neon + +unsigned int vpx_sad8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +unsigned int vpx_sad8x8_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride); +#define vpx_sad8x8 vpx_sad8x8_neon + +unsigned int vpx_sad8x8_avg_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +unsigned int vpx_sad8x8_avg_neon(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, const uint8_t *second_pred); +#define vpx_sad8x8_avg vpx_sad8x8_avg_neon + +void vpx_sad8x8x3_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad8x8x3 vpx_sad8x8x3_c + +void vpx_sad8x8x4d_c(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +void vpx_sad8x8x4d_neon(const uint8_t *src_ptr, int src_stride, const uint8_t * const ref_ptr[], int ref_stride, uint32_t *sad_array); +#define vpx_sad8x8x4d vpx_sad8x8x4d_neon + +void vpx_sad8x8x8_c(const uint8_t *src_ptr, int src_stride, const uint8_t *ref_ptr, int ref_stride, uint32_t *sad_array); +#define vpx_sad8x8x8 vpx_sad8x8x8_c + +int vpx_satd_c(const int16_t *coeff, int length); +int vpx_satd_neon(const int16_t *coeff, int length); +#define vpx_satd vpx_satd_neon + +void vpx_scaled_2d_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +void vpx_scaled_2d_neon(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_2d vpx_scaled_2d_neon + +void vpx_scaled_avg_2d_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_avg_2d vpx_scaled_avg_2d_c + +void vpx_scaled_avg_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_avg_horiz vpx_scaled_avg_horiz_c + +void vpx_scaled_avg_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_avg_vert vpx_scaled_avg_vert_c + +void vpx_scaled_horiz_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_horiz vpx_scaled_horiz_c + +void vpx_scaled_vert_c(const uint8_t *src, ptrdiff_t src_stride, uint8_t *dst, ptrdiff_t dst_stride, const InterpKernel *filter, int x0_q4, int x_step_q4, int y0_q4, int y_step_q4, int w, int h); +#define vpx_scaled_vert vpx_scaled_vert_c + +uint32_t vpx_sub_pixel_avg_variance16x16_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance16x16_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance16x16 vpx_sub_pixel_avg_variance16x16_neon + +uint32_t vpx_sub_pixel_avg_variance16x32_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance16x32_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance16x32 vpx_sub_pixel_avg_variance16x32_neon + +uint32_t vpx_sub_pixel_avg_variance16x8_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance16x8_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance16x8 vpx_sub_pixel_avg_variance16x8_neon + +uint32_t vpx_sub_pixel_avg_variance32x16_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance32x16_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance32x16 vpx_sub_pixel_avg_variance32x16_neon + +uint32_t vpx_sub_pixel_avg_variance32x32_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance32x32_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance32x32 vpx_sub_pixel_avg_variance32x32_neon + +uint32_t vpx_sub_pixel_avg_variance32x64_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance32x64_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance32x64 vpx_sub_pixel_avg_variance32x64_neon + +uint32_t vpx_sub_pixel_avg_variance4x4_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance4x4_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance4x4 vpx_sub_pixel_avg_variance4x4_neon + +uint32_t vpx_sub_pixel_avg_variance4x8_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance4x8_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance4x8 vpx_sub_pixel_avg_variance4x8_neon + +uint32_t vpx_sub_pixel_avg_variance64x32_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance64x32_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance64x32 vpx_sub_pixel_avg_variance64x32_neon + +uint32_t vpx_sub_pixel_avg_variance64x64_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance64x64_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance64x64 vpx_sub_pixel_avg_variance64x64_neon + +uint32_t vpx_sub_pixel_avg_variance8x16_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance8x16_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance8x16 vpx_sub_pixel_avg_variance8x16_neon + +uint32_t vpx_sub_pixel_avg_variance8x4_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance8x4_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance8x4 vpx_sub_pixel_avg_variance8x4_neon + +uint32_t vpx_sub_pixel_avg_variance8x8_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +uint32_t vpx_sub_pixel_avg_variance8x8_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse, const uint8_t *second_pred); +#define vpx_sub_pixel_avg_variance8x8 vpx_sub_pixel_avg_variance8x8_neon + +uint32_t vpx_sub_pixel_variance16x16_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance16x16_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance16x16 vpx_sub_pixel_variance16x16_neon + +uint32_t vpx_sub_pixel_variance16x32_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance16x32_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance16x32 vpx_sub_pixel_variance16x32_neon + +uint32_t vpx_sub_pixel_variance16x8_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance16x8_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance16x8 vpx_sub_pixel_variance16x8_neon + +uint32_t vpx_sub_pixel_variance32x16_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance32x16_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance32x16 vpx_sub_pixel_variance32x16_neon + +uint32_t vpx_sub_pixel_variance32x32_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance32x32_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance32x32 vpx_sub_pixel_variance32x32_neon + +uint32_t vpx_sub_pixel_variance32x64_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance32x64_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance32x64 vpx_sub_pixel_variance32x64_neon + +uint32_t vpx_sub_pixel_variance4x4_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance4x4_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance4x4 vpx_sub_pixel_variance4x4_neon + +uint32_t vpx_sub_pixel_variance4x8_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance4x8_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance4x8 vpx_sub_pixel_variance4x8_neon + +uint32_t vpx_sub_pixel_variance64x32_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance64x32_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance64x32 vpx_sub_pixel_variance64x32_neon + +uint32_t vpx_sub_pixel_variance64x64_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance64x64_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance64x64 vpx_sub_pixel_variance64x64_neon + +uint32_t vpx_sub_pixel_variance8x16_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance8x16_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance8x16 vpx_sub_pixel_variance8x16_neon + +uint32_t vpx_sub_pixel_variance8x4_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance8x4_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance8x4 vpx_sub_pixel_variance8x4_neon + +uint32_t vpx_sub_pixel_variance8x8_c(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +uint32_t vpx_sub_pixel_variance8x8_neon(const uint8_t *src_ptr, int source_stride, int xoffset, int yoffset, const uint8_t *ref_ptr, int ref_stride, uint32_t *sse); +#define vpx_sub_pixel_variance8x8 vpx_sub_pixel_variance8x8_neon + +void vpx_subtract_block_c(int rows, int cols, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride); +void vpx_subtract_block_neon(int rows, int cols, int16_t *diff_ptr, ptrdiff_t diff_stride, const uint8_t *src_ptr, ptrdiff_t src_stride, const uint8_t *pred_ptr, ptrdiff_t pred_stride); +#define vpx_subtract_block vpx_subtract_block_neon + +uint64_t vpx_sum_squares_2d_i16_c(const int16_t *src, int stride, int size); +#define vpx_sum_squares_2d_i16 vpx_sum_squares_2d_i16_c + +void vpx_tm_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_tm_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_16x16 vpx_tm_predictor_16x16_neon + +void vpx_tm_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_tm_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_32x32 vpx_tm_predictor_32x32_neon + +void vpx_tm_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_tm_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_4x4 vpx_tm_predictor_4x4_neon + +void vpx_tm_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_tm_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_tm_predictor_8x8 vpx_tm_predictor_8x8_neon + +void vpx_v_predictor_16x16_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_v_predictor_16x16_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_16x16 vpx_v_predictor_16x16_neon + +void vpx_v_predictor_32x32_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_v_predictor_32x32_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_32x32 vpx_v_predictor_32x32_neon + +void vpx_v_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_v_predictor_4x4_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_4x4 vpx_v_predictor_4x4_neon + +void vpx_v_predictor_8x8_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +void vpx_v_predictor_8x8_neon(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_v_predictor_8x8 vpx_v_predictor_8x8_neon + +unsigned int vpx_variance16x16_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance16x16_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance16x16 vpx_variance16x16_neon + +unsigned int vpx_variance16x32_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance16x32_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance16x32 vpx_variance16x32_neon + +unsigned int vpx_variance16x8_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance16x8_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance16x8 vpx_variance16x8_neon + +unsigned int vpx_variance32x16_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance32x16_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance32x16 vpx_variance32x16_neon + +unsigned int vpx_variance32x32_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance32x32_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance32x32 vpx_variance32x32_neon + +unsigned int vpx_variance32x64_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance32x64_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance32x64 vpx_variance32x64_neon + +unsigned int vpx_variance4x4_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance4x4_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance4x4 vpx_variance4x4_neon + +unsigned int vpx_variance4x8_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance4x8_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance4x8 vpx_variance4x8_neon + +unsigned int vpx_variance64x32_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance64x32_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance64x32 vpx_variance64x32_neon + +unsigned int vpx_variance64x64_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance64x64_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance64x64 vpx_variance64x64_neon + +unsigned int vpx_variance8x16_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance8x16_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance8x16 vpx_variance8x16_neon + +unsigned int vpx_variance8x4_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance8x4_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance8x4 vpx_variance8x4_neon + +unsigned int vpx_variance8x8_c(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +unsigned int vpx_variance8x8_neon(const uint8_t *src_ptr, int source_stride, const uint8_t *ref_ptr, int ref_stride, unsigned int *sse); +#define vpx_variance8x8 vpx_variance8x8_neon + +void vpx_ve_predictor_4x4_c(uint8_t *dst, ptrdiff_t y_stride, const uint8_t *above, const uint8_t *left); +#define vpx_ve_predictor_4x4 vpx_ve_predictor_4x4_c + +int vpx_vector_var_c(const int16_t *ref, const int16_t *src, const int bwl); +int vpx_vector_var_neon(const int16_t *ref, const int16_t *src, const int bwl); +#define vpx_vector_var vpx_vector_var_neon + +void vpx_dsp_rtcd(void); + +#include "vpx_config.h" + +#ifdef RTCD_C +#include "vpx_ports/arm.h" +static void setup_rtcd_internal(void) +{ + int flags = arm_cpu_caps(); + + (void)flags; + +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/media/libvpx/config/linux/arm64/vpx_scale_rtcd.h b/media/libvpx/config/linux/arm64/vpx_scale_rtcd.h new file mode 100644 index 000000000000..b37136827560 --- /dev/null +++ b/media/libvpx/config/linux/arm64/vpx_scale_rtcd.h @@ -0,0 +1,75 @@ +// This file is generated. Do not edit. +#ifndef VPX_SCALE_RTCD_H_ +#define VPX_SCALE_RTCD_H_ + +#ifdef RTCD_C +#define RTCD_EXTERN +#else +#define RTCD_EXTERN extern +#endif + +struct yv12_buffer_config; + +#ifdef __cplusplus +extern "C" { +#endif + +void vp8_horizontal_line_2_1_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width); +#define vp8_horizontal_line_2_1_scale vp8_horizontal_line_2_1_scale_c + +void vp8_horizontal_line_5_3_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width); +#define vp8_horizontal_line_5_3_scale vp8_horizontal_line_5_3_scale_c + +void vp8_horizontal_line_5_4_scale_c(const unsigned char *source, unsigned int source_width, unsigned char *dest, unsigned int dest_width); +#define vp8_horizontal_line_5_4_scale vp8_horizontal_line_5_4_scale_c + +void vp8_vertical_band_2_1_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_2_1_scale vp8_vertical_band_2_1_scale_c + +void vp8_vertical_band_2_1_scale_i_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_2_1_scale_i vp8_vertical_band_2_1_scale_i_c + +void vp8_vertical_band_5_3_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_5_3_scale vp8_vertical_band_5_3_scale_c + +void vp8_vertical_band_5_4_scale_c(unsigned char *source, unsigned int src_pitch, unsigned char *dest, unsigned int dest_pitch, unsigned int dest_width); +#define vp8_vertical_band_5_4_scale vp8_vertical_band_5_4_scale_c + +void vp8_yv12_copy_frame_c(const struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc); +#define vp8_yv12_copy_frame vp8_yv12_copy_frame_c + +void vp8_yv12_extend_frame_borders_c(struct yv12_buffer_config *ybf); +#define vp8_yv12_extend_frame_borders vp8_yv12_extend_frame_borders_c + +void vpx_extend_frame_borders_c(struct yv12_buffer_config *ybf); +#define vpx_extend_frame_borders vpx_extend_frame_borders_c + +void vpx_extend_frame_inner_borders_c(struct yv12_buffer_config *ybf); +#define vpx_extend_frame_inner_borders vpx_extend_frame_inner_borders_c + +void vpx_yv12_copy_frame_c(const struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc); +#define vpx_yv12_copy_frame vpx_yv12_copy_frame_c + +void vpx_yv12_copy_y_c(const struct yv12_buffer_config *src_ybc, struct yv12_buffer_config *dst_ybc); +#define vpx_yv12_copy_y vpx_yv12_copy_y_c + +void vpx_scale_rtcd(void); + +#include "vpx_config.h" + +#ifdef RTCD_C +#include "vpx_ports/arm.h" +static void setup_rtcd_internal(void) +{ + int flags = arm_cpu_caps(); + + (void)flags; + +} +#endif + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/media/libvpx/sources.mozbuild b/media/libvpx/sources.mozbuild index ba3f78f340ac..1601ad115989 100644 --- a/media/libvpx/sources.mozbuild +++ b/media/libvpx/sources.mozbuild @@ -756,6 +756,235 @@ files = { 'libvpx/vpx_scale/vpx_scale_rtcd.c', 'libvpx/vpx_util/vpx_thread.c', 'libvpx/vpx_util/vpx_write_yuv_frame.c', +], + 'ARM64_EXPORTS': [ + 'libvpx/vpx/vp8.h', + 'libvpx/vpx/vp8cx.h', + 'libvpx/vpx/vp8dx.h', + 'libvpx/vpx/vpx_codec.h', + 'libvpx/vpx/vpx_decoder.h', + 'libvpx/vpx/vpx_encoder.h', + 'libvpx/vpx/vpx_frame_buffer.h', + 'libvpx/vpx/vpx_image.h', + 'libvpx/vpx/vpx_integer.h', + 'libvpx/vpx_mem/include/vpx_mem_intrnl.h', + 'libvpx/vpx_mem/vpx_mem.h', + 'libvpx/vpx_ports/arm.h', + 'libvpx/vpx_ports/bitops.h', + 'libvpx/vpx_ports/mem.h', + 'libvpx/vpx_ports/system_state.h', + 'libvpx/vpx_ports/vpx_timer.h', + 'libvpx/vpx_scale/vpx_scale.h', + 'libvpx/vpx_scale/yv12config.h', +], + 'ARM64_SOURCES': [ + 'libvpx/vp8/common/alloccommon.c', + 'libvpx/vp8/common/arm/loopfilter_arm.c', + 'libvpx/vp8/common/arm/neon/bilinearpredict_neon.c', + 'libvpx/vp8/common/arm/neon/copymem_neon.c', + 'libvpx/vp8/common/arm/neon/dc_only_idct_add_neon.c', + 'libvpx/vp8/common/arm/neon/dequant_idct_neon.c', + 'libvpx/vp8/common/arm/neon/dequantizeb_neon.c', + 'libvpx/vp8/common/arm/neon/idct_blk_neon.c', + 'libvpx/vp8/common/arm/neon/idct_dequant_0_2x_neon.c', + 'libvpx/vp8/common/arm/neon/idct_dequant_full_2x_neon.c', + 'libvpx/vp8/common/arm/neon/iwalsh_neon.c', + 'libvpx/vp8/common/arm/neon/loopfiltersimplehorizontaledge_neon.c', + 'libvpx/vp8/common/arm/neon/loopfiltersimpleverticaledge_neon.c', + 'libvpx/vp8/common/arm/neon/mbloopfilter_neon.c', + 'libvpx/vp8/common/arm/neon/shortidct4x4llm_neon.c', + 'libvpx/vp8/common/arm/neon/sixtappredict_neon.c', + 'libvpx/vp8/common/arm/neon/vp8_loopfilter_neon.c', + 'libvpx/vp8/common/blockd.c', + 'libvpx/vp8/common/copy_c.c', + 'libvpx/vp8/common/dequantize.c', + 'libvpx/vp8/common/entropy.c', + 'libvpx/vp8/common/entropymode.c', + 'libvpx/vp8/common/entropymv.c', + 'libvpx/vp8/common/extend.c', + 'libvpx/vp8/common/filter.c', + 'libvpx/vp8/common/findnearmv.c', + 'libvpx/vp8/common/generic/systemdependent.c', + 'libvpx/vp8/common/idct_blk.c', + 'libvpx/vp8/common/idctllm.c', + 'libvpx/vp8/common/loopfilter_filters.c', + 'libvpx/vp8/common/mbpitch.c', + 'libvpx/vp8/common/modecont.c', + 'libvpx/vp8/common/quant_common.c', + 'libvpx/vp8/common/reconinter.c', + 'libvpx/vp8/common/reconintra.c', + 'libvpx/vp8/common/reconintra4x4.c', + 'libvpx/vp8/common/rtcd.c', + 'libvpx/vp8/common/setupintrarecon.c', + 'libvpx/vp8/common/swapyv12buffer.c', + 'libvpx/vp8/common/treecoder.c', + 'libvpx/vp8/common/vp8_loopfilter.c', + 'libvpx/vp8/common/vp8_skin_detection.c', + 'libvpx/vp8/decoder/dboolhuff.c', + 'libvpx/vp8/decoder/decodeframe.c', + 'libvpx/vp8/decoder/decodemv.c', + 'libvpx/vp8/decoder/detokenize.c', + 'libvpx/vp8/decoder/onyxd_if.c', + 'libvpx/vp8/decoder/threading.c', + 'libvpx/vp8/encoder/arm/neon/denoising_neon.c', + 'libvpx/vp8/encoder/arm/neon/fastquantizeb_neon.c', + 'libvpx/vp8/encoder/arm/neon/shortfdct_neon.c', + 'libvpx/vp8/encoder/arm/neon/vp8_shortwalsh4x4_neon.c', + 'libvpx/vp8/encoder/bitstream.c', + 'libvpx/vp8/encoder/boolhuff.c', + 'libvpx/vp8/encoder/dct.c', + 'libvpx/vp8/encoder/denoising.c', + 'libvpx/vp8/encoder/encodeframe.c', + 'libvpx/vp8/encoder/encodeintra.c', + 'libvpx/vp8/encoder/encodemb.c', + 'libvpx/vp8/encoder/encodemv.c', + 'libvpx/vp8/encoder/ethreading.c', + 'libvpx/vp8/encoder/lookahead.c', + 'libvpx/vp8/encoder/mcomp.c', + 'libvpx/vp8/encoder/modecosts.c', + 'libvpx/vp8/encoder/mr_dissim.c', + 'libvpx/vp8/encoder/onyx_if.c', + 'libvpx/vp8/encoder/pickinter.c', + 'libvpx/vp8/encoder/picklpf.c', + 'libvpx/vp8/encoder/ratectrl.c', + 'libvpx/vp8/encoder/rdopt.c', + 'libvpx/vp8/encoder/segmentation.c', + 'libvpx/vp8/encoder/tokenize.c', + 'libvpx/vp8/encoder/treewriter.c', + 'libvpx/vp8/encoder/vp8_quantize.c', + 'libvpx/vp8/vp8_cx_iface.c', + 'libvpx/vp8/vp8_dx_iface.c', + 'libvpx/vp9/common/arm/neon/vp9_iht4x4_add_neon.c', + 'libvpx/vp9/common/arm/neon/vp9_iht8x8_add_neon.c', + 'libvpx/vp9/common/vp9_alloccommon.c', + 'libvpx/vp9/common/vp9_blockd.c', + 'libvpx/vp9/common/vp9_common_data.c', + 'libvpx/vp9/common/vp9_entropy.c', + 'libvpx/vp9/common/vp9_entropymode.c', + 'libvpx/vp9/common/vp9_entropymv.c', + 'libvpx/vp9/common/vp9_filter.c', + 'libvpx/vp9/common/vp9_frame_buffers.c', + 'libvpx/vp9/common/vp9_idct.c', + 'libvpx/vp9/common/vp9_loopfilter.c', + 'libvpx/vp9/common/vp9_mvref_common.c', + 'libvpx/vp9/common/vp9_pred_common.c', + 'libvpx/vp9/common/vp9_quant_common.c', + 'libvpx/vp9/common/vp9_reconinter.c', + 'libvpx/vp9/common/vp9_reconintra.c', + 'libvpx/vp9/common/vp9_rtcd.c', + 'libvpx/vp9/common/vp9_scale.c', + 'libvpx/vp9/common/vp9_scan.c', + 'libvpx/vp9/common/vp9_seg_common.c', + 'libvpx/vp9/common/vp9_thread_common.c', + 'libvpx/vp9/common/vp9_tile_common.c', + 'libvpx/vp9/decoder/vp9_decodeframe.c', + 'libvpx/vp9/decoder/vp9_decodemv.c', + 'libvpx/vp9/decoder/vp9_decoder.c', + 'libvpx/vp9/decoder/vp9_detokenize.c', + 'libvpx/vp9/decoder/vp9_dsubexp.c', + 'libvpx/vp9/encoder/arm/neon/vp9_dct_neon.c', + 'libvpx/vp9/encoder/arm/neon/vp9_error_neon.c', + 'libvpx/vp9/encoder/arm/neon/vp9_frame_scale_neon.c', + 'libvpx/vp9/encoder/arm/neon/vp9_quantize_neon.c', + 'libvpx/vp9/encoder/vp9_alt_ref_aq.c', + 'libvpx/vp9/encoder/vp9_aq_360.c', + 'libvpx/vp9/encoder/vp9_aq_complexity.c', + 'libvpx/vp9/encoder/vp9_aq_cyclicrefresh.c', + 'libvpx/vp9/encoder/vp9_aq_variance.c', + 'libvpx/vp9/encoder/vp9_bitstream.c', + 'libvpx/vp9/encoder/vp9_context_tree.c', + 'libvpx/vp9/encoder/vp9_cost.c', + 'libvpx/vp9/encoder/vp9_dct.c', + 'libvpx/vp9/encoder/vp9_encodeframe.c', + 'libvpx/vp9/encoder/vp9_encodemb.c', + 'libvpx/vp9/encoder/vp9_encodemv.c', + 'libvpx/vp9/encoder/vp9_encoder.c', + 'libvpx/vp9/encoder/vp9_ethread.c', + 'libvpx/vp9/encoder/vp9_extend.c', + 'libvpx/vp9/encoder/vp9_frame_scale.c', + 'libvpx/vp9/encoder/vp9_lookahead.c', + 'libvpx/vp9/encoder/vp9_mcomp.c', + 'libvpx/vp9/encoder/vp9_multi_thread.c', + 'libvpx/vp9/encoder/vp9_noise_estimate.c', + 'libvpx/vp9/encoder/vp9_picklpf.c', + 'libvpx/vp9/encoder/vp9_pickmode.c', + 'libvpx/vp9/encoder/vp9_quantize.c', + 'libvpx/vp9/encoder/vp9_ratectrl.c', + 'libvpx/vp9/encoder/vp9_rd.c', + 'libvpx/vp9/encoder/vp9_rdopt.c', + 'libvpx/vp9/encoder/vp9_resize.c', + 'libvpx/vp9/encoder/vp9_segmentation.c', + 'libvpx/vp9/encoder/vp9_skin_detection.c', + 'libvpx/vp9/encoder/vp9_speed_features.c', + 'libvpx/vp9/encoder/vp9_subexp.c', + 'libvpx/vp9/encoder/vp9_svc_layercontext.c', + 'libvpx/vp9/encoder/vp9_tokenize.c', + 'libvpx/vp9/encoder/vp9_treewriter.c', + 'libvpx/vp9/vp9_cx_iface.c', + 'libvpx/vp9/vp9_dx_iface.c', + 'libvpx/vpx/src/vpx_codec.c', + 'libvpx/vpx/src/vpx_decoder.c', + 'libvpx/vpx/src/vpx_encoder.c', + 'libvpx/vpx/src/vpx_image.c', + 'libvpx/vpx_dsp/arm/avg_neon.c', + 'libvpx/vpx_dsp/arm/avg_pred_neon.c', + 'libvpx/vpx_dsp/arm/fdct16x16_neon.c', + 'libvpx/vpx_dsp/arm/fdct32x32_neon.c', + 'libvpx/vpx_dsp/arm/fdct_neon.c', + 'libvpx/vpx_dsp/arm/fdct_partial_neon.c', + 'libvpx/vpx_dsp/arm/fwd_txfm_neon.c', + 'libvpx/vpx_dsp/arm/hadamard_neon.c', + 'libvpx/vpx_dsp/arm/idct16x16_1_add_neon.c', + 'libvpx/vpx_dsp/arm/idct16x16_add_neon.c', + 'libvpx/vpx_dsp/arm/idct32x32_135_add_neon.c', + 'libvpx/vpx_dsp/arm/idct32x32_1_add_neon.c', + 'libvpx/vpx_dsp/arm/idct32x32_34_add_neon.c', + 'libvpx/vpx_dsp/arm/idct32x32_add_neon.c', + 'libvpx/vpx_dsp/arm/idct4x4_1_add_neon.c', + 'libvpx/vpx_dsp/arm/idct4x4_add_neon.c', + 'libvpx/vpx_dsp/arm/idct8x8_1_add_neon.c', + 'libvpx/vpx_dsp/arm/idct8x8_add_neon.c', + 'libvpx/vpx_dsp/arm/intrapred_neon.c', + 'libvpx/vpx_dsp/arm/loopfilter_neon.c', + 'libvpx/vpx_dsp/arm/quantize_neon.c', + 'libvpx/vpx_dsp/arm/sad4d_neon.c', + 'libvpx/vpx_dsp/arm/sad_neon.c', + 'libvpx/vpx_dsp/arm/subpel_variance_neon.c', + 'libvpx/vpx_dsp/arm/subtract_neon.c', + 'libvpx/vpx_dsp/arm/variance_neon.c', + 'libvpx/vpx_dsp/arm/vpx_convolve8_neon.c', + 'libvpx/vpx_dsp/arm/vpx_convolve_avg_neon.c', + 'libvpx/vpx_dsp/arm/vpx_convolve_copy_neon.c', + 'libvpx/vpx_dsp/arm/vpx_convolve_neon.c', + 'libvpx/vpx_dsp/arm/vpx_scaled_convolve8_neon.c', + 'libvpx/vpx_dsp/avg.c', + 'libvpx/vpx_dsp/bitreader.c', + 'libvpx/vpx_dsp/bitreader_buffer.c', + 'libvpx/vpx_dsp/bitwriter.c', + 'libvpx/vpx_dsp/bitwriter_buffer.c', + 'libvpx/vpx_dsp/fwd_txfm.c', + 'libvpx/vpx_dsp/intrapred.c', + 'libvpx/vpx_dsp/inv_txfm.c', + 'libvpx/vpx_dsp/loopfilter.c', + 'libvpx/vpx_dsp/prob.c', + 'libvpx/vpx_dsp/psnr.c', + 'libvpx/vpx_dsp/quantize.c', + 'libvpx/vpx_dsp/sad.c', + 'libvpx/vpx_dsp/skin_detection.c', + 'libvpx/vpx_dsp/subtract.c', + 'libvpx/vpx_dsp/sum_squares.c', + 'libvpx/vpx_dsp/variance.c', + 'libvpx/vpx_dsp/vpx_convolve.c', + 'libvpx/vpx_dsp/vpx_dsp_rtcd.c', + 'libvpx/vpx_mem/vpx_mem.c', + 'libvpx/vpx_ports/arm_cpudetect.c', + 'libvpx/vpx_scale/generic/gen_scalers.c', + 'libvpx/vpx_scale/generic/vpx_scale.c', + 'libvpx/vpx_scale/generic/yv12config.c', + 'libvpx/vpx_scale/generic/yv12extend.c', + 'libvpx/vpx_scale/vpx_scale_rtcd.c', + 'libvpx/vpx_util/vpx_thread.c', + 'libvpx/vpx_util/vpx_write_yuv_frame.c', ], 'GENERIC_EXPORTS': [ 'libvpx/vpx/vp8.h', From e37f3348daf3f7818ace8de559bc1029cc85adb3 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 04:46:21 +0000 Subject: [PATCH 03/33] Bug 1521433. Fix non-unified build failure in nsXHTMLContentSerializer.cpp. r=emilio Differential Revision: https://phabricator.services.mozilla.com/D17087 --HG-- extra : moz-landing-system : lando --- dom/base/nsXHTMLContentSerializer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dom/base/nsXHTMLContentSerializer.cpp b/dom/base/nsXHTMLContentSerializer.cpp index 6ae477e217de..76ade6a72f7f 100644 --- a/dom/base/nsXHTMLContentSerializer.cpp +++ b/dom/base/nsXHTMLContentSerializer.cpp @@ -33,6 +33,7 @@ #include "nsComputedDOMStyle.h" using namespace mozilla; +using namespace mozilla::dom; static const int32_t kLongLineLen = 128; @@ -419,7 +420,7 @@ bool nsXHTMLContentSerializer::CheckElementStart(Element* aElement, return true; } -bool nsXHTMLContentSerializer::CheckElementEnd(dom::Element* aElement, +bool nsXHTMLContentSerializer::CheckElementEnd(Element* aElement, bool& aForceFormat, nsAString& aStr) { NS_ASSERTION(!mIsHTMLSerializer, From 67be15b8fcfac0e609be03e917749c3590b50faf Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:24:42 +0000 Subject: [PATCH 04/33] Bug 1363208 part 1. Add a MaybeWrapObject function that works on JSObject* instead of JS::Value. r=peterv,bholley Differential Revision: https://phabricator.services.mozilla.com/D15424 --HG-- extra : moz-landing-system : lando --- dom/bindings/BindingUtils.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 94e6fff0635b..27f536029deb 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -782,6 +782,16 @@ inline bool TryToOuterize(JS::MutableHandle rval) { return true; } +inline bool TryToOuterize(JS::MutableHandle obj) { + if (js::IsWindow(obj)) { + JSObject* proxy = js::ToWindowProxyIfWindow(obj); + MOZ_ASSERT(proxy); + obj.set(proxy); + } + + return true; +} + // Make sure to wrap the given string value into the right compartment, as // needed. MOZ_ALWAYS_INLINE @@ -817,6 +827,25 @@ bool MaybeWrapObjectValue(JSContext* cx, JS::MutableHandle rval) { return true; } +// Like MaybeWrapObjectValue, but working with a +// JS::MutableHandle which must be non-null. +MOZ_ALWAYS_INLINE +bool MaybeWrapObject(JSContext* cx, JS::MutableHandle obj) { + if (js::GetObjectCompartment(obj) != js::GetContextCompartment(cx)) { + return JS_WrapObject(cx, obj); + } + + // We're same-compartment, but even then we might need to wrap + // objects specially. Check for that. + if (IsDOMObject(obj)) { + return TryToOuterize(obj); + } + + // It's not a WebIDL object, so it's OK to just leave it as-is: only WebIDL + // objects (specifically only windows) require outerization. + return true; +} + // Like MaybeWrapObjectValue, but also allows null MOZ_ALWAYS_INLINE bool MaybeWrapObjectOrNullValue(JSContext* cx, From 79d353e3bc8f9bfb2e3177a3ac1519e9e6189c5f Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:28:06 +0000 Subject: [PATCH 05/33] Bug 1363208 part 2. Add a helper class for implementing the HTML requirements for cross-origin-accessible objects. r=jandem,peterv Differential Revision: https://phabricator.services.mozilla.com/D15425 --HG-- extra : moz-landing-system : lando --- dom/base/MaybeCrossOriginObject.cpp | 433 ++++++++++++++++++++++++++++ dom/base/MaybeCrossOriginObject.h | 325 +++++++++++++++++++++ dom/base/RemoteOuterWindowProxy.cpp | 5 +- dom/base/moz.build | 2 + dom/bindings/RemoteObjectProxy.cpp | 65 +---- dom/bindings/RemoteObjectProxy.h | 92 ++---- 6 files changed, 798 insertions(+), 124 deletions(-) create mode 100644 dom/base/MaybeCrossOriginObject.cpp create mode 100644 dom/base/MaybeCrossOriginObject.h diff --git a/dom/base/MaybeCrossOriginObject.cpp b/dom/base/MaybeCrossOriginObject.cpp new file mode 100644 index 000000000000..327310893f68 --- /dev/null +++ b/dom/base/MaybeCrossOriginObject.cpp @@ -0,0 +1,433 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "mozilla/dom/MaybeCrossOriginObject.h" + +#include "mozilla/BasePrincipal.h" +#include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/RemoteObjectProxy.h" +#include "js/Proxy.h" +#include "js/RootingAPI.h" +#include "js/Wrapper.h" +#include "jsfriendapi.h" +#include "AccessCheck.h" +#include "nsContentUtils.h" + +#ifdef DEBUG +static bool IsLocation(JSObject* obj) { + return strcmp(js::GetObjectClass(obj)->name, "Location") == 0; +} +#endif // DEBUG + +namespace mozilla { +namespace dom { + +/* static */ +bool MaybeCrossOriginObjectMixins::IsPlatformObjectSameOrigin( + JSContext* cx, JS::Handle obj) { + MOZ_ASSERT(!js::IsCrossCompartmentWrapper(obj)); + // WindowProxy and Window must always be same-Realm, so we can do + // our IsPlatformObjectSameOrigin check against either one. But verify that + // in case we have a WindowProxy the right things happen. + MOZ_ASSERT(js::GetNonCCWObjectRealm(obj) == + // "true" for second arg means to unwrap WindowProxy to + // get at the Window. + js::GetNonCCWObjectRealm(js::UncheckedUnwrap(obj, true)), + "WindowProxy not same-Realm as Window?"); + + BasePrincipal* subjectPrincipal = + BasePrincipal::Cast(nsContentUtils::SubjectPrincipal(cx)); + nsIPrincipal* objectPrincipal = nsContentUtils::ObjectPrincipal(obj); + + // The spec effectively has an EqualsConsideringDomain check here, + // because the spec has no concept of asymmetric security + // relationships. But we shouldn't ever end up here in the + // asymmetric case anyway: That case should end up with Xrays, which + // don't call into this code. + // + // Let's assert that EqualsConsideringDomain and + // SubsumesConsideringDomain give the same results and use + // EqualsConsideringDomain for the check we actually do, since it's + // stricter and more closely matches the spec. + MOZ_ASSERT( + subjectPrincipal->FastEqualsConsideringDomain(objectPrincipal) == + subjectPrincipal->FastSubsumesConsideringDomain(objectPrincipal), + "Why are we in an asymmetric case here?"); + return subjectPrincipal->FastEqualsConsideringDomain(objectPrincipal); +} + +bool MaybeCrossOriginObjectMixins::CrossOriginGetOwnPropertyHelper( + JSContext* cx, JS::Handle obj, JS::Handle id, + JS::MutableHandle desc) const { + MOZ_ASSERT(!IsPlatformObjectSameOrigin(cx, obj) || IsRemoteObjectProxy(obj), + "Why did we get called?"); + // First check for an IDL-defined cross-origin property with the given name. + // This corresponds to + // https://html.spec.whatwg.org/multipage/browsers.html#crossorigingetownpropertyhelper-(-o,-p-) + // step 2. + JS::Rooted holder(cx); + if (!EnsureHolder(cx, obj, &holder)) { + return false; + } + + if (!JS_GetOwnPropertyDescriptorById(cx, holder, id, desc)) { + return false; + } + + if (desc.object()) { + desc.object().set(obj); + } + + return true; +} + +/* static */ +bool MaybeCrossOriginObjectMixins::CrossOriginPropertyFallback( + JSContext* cx, JS::Handle obj, JS::Handle id, + JS::MutableHandle desc) { + MOZ_ASSERT(!desc.object(), "Why are we being called?"); + + // Step 1. + if (xpc::IsCrossOriginWhitelistedProp(cx, id)) { + // Spec says to return PropertyDescriptor { + // [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, + // [[Configurable]]: true + // }. + desc.setDataDescriptor(JS::UndefinedHandleValue, JSPROP_READONLY); + desc.object().set(obj); + return true; + } + + // Step 2. + return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("access")); +} + +/* static */ +bool MaybeCrossOriginObjectMixins::CrossOriginGet( + JSContext* cx, JS::Handle obj, JS::Handle receiver, + JS::Handle id, JS::MutableHandle vp) { + // This is fairly similar to BaseProxyHandler::get, but there are some + // differences. Most importantly, we want to throw if we have a descriptor + // with no getter, while BaseProxyHandler::get returns undefined. The other + // big difference is that we don't have to worry about prototypes (ours is + // always null). + + // We want to invoke [[GetOwnProperty]] on "obj", but _without_ entering its + // compartment, because for the proxies we have here [[GetOwnProperty]] will + // do security checks based on the current Realm. Unfortunately, + // JS_GetPropertyDescriptorById asserts that compartments match. Luckily, we + // know that "obj" is a proxy here, so we can directly call its + // getOwnPropertyDescriptor() hook. + // + // It looks like Proxy::getOwnPropertyDescriptor is not public, so just grab + // the handler and call its getOwnPropertyDescriptor hook directly. + MOZ_ASSERT(js::IsProxy(obj), "How did we get a bogus object here?"); + MOZ_ASSERT( + js::IsWindowProxy(obj) || IsLocation(obj) || IsRemoteObjectProxy(obj), + "Unexpected proxy"); + MOZ_ASSERT(!IsPlatformObjectSameOrigin(cx, obj) || IsRemoteObjectProxy(obj), + "Why did we get called?"); + js::AssertSameCompartment(cx, receiver); + + // Step 1. + JS::Rooted desc(cx); + if (!js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, obj, id, &desc)) { + return false; + } + desc.assertCompleteIfFound(); + + // Step 2. + MOZ_ASSERT(desc.object(), + "Callees should throw in all cases when they are not finding a " + "property decriptor"); + + // Step 3. + if (desc.isDataDescriptor()) { + vp.set(desc.value()); + return true; + } + + // Step 4. + MOZ_ASSERT(desc.isAccessorDescriptor()); + + // Step 5. + JS::Rooted getter(cx); + if (!desc.hasGetterObject() || !(getter = desc.getterObject())) { + // Step 6. + return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("get")); + } + + // Step 7. + return JS::Call(cx, receiver, getter, JS::HandleValueArray::empty(), vp); +} + +/* static */ +bool MaybeCrossOriginObjectMixins::CrossOriginSet( + JSContext* cx, JS::Handle obj, JS::Handle id, + JS::Handle v, JS::Handle receiver, + JS::ObjectOpResult& result) { + // We want to invoke [[GetOwnProperty]] on "obj", but _without_ entering its + // compartment, because for the proxies we have here [[GetOwnProperty]] will + // do security checks based on the current Realm. Unfortunately, + // JS_GetPropertyDescriptorById asserts that compartments match. Luckily, we + // know that "obj" is a proxy here, so we can directly call its + // getOwnPropertyDescriptor() hook. + // + // It looks like Proxy::getOwnPropertyDescriptor is not public, so just grab + // the handler and call its getOwnPropertyDescriptor hook directly. + MOZ_ASSERT(js::IsProxy(obj), "How did we get a bogus object here?"); + MOZ_ASSERT( + js::IsWindowProxy(obj) || IsLocation(obj) || IsRemoteObjectProxy(obj), + "Unexpected proxy"); + MOZ_ASSERT(!IsPlatformObjectSameOrigin(cx, obj) || IsRemoteObjectProxy(obj), + "Why did we get called?"); + js::AssertSameCompartment(cx, receiver); + js::AssertSameCompartment(cx, v); + + // Step 1. + JS::Rooted desc(cx); + if (!js::GetProxyHandler(obj)->getOwnPropertyDescriptor(cx, obj, id, &desc)) { + return false; + } + desc.assertCompleteIfFound(); + + // Step 2. + MOZ_ASSERT(desc.object(), + "Callees should throw in all cases when they are not finding a " + "property decriptor"); + + // Step 3. + JS::Rooted setter(cx); + if (desc.hasSetterObject() && (setter = desc.setterObject())) { + JS::Rooted ignored(cx); + // Step 3.1. + if (!JS::Call(cx, receiver, setter, JS::HandleValueArray(v), &ignored)) { + return false; + } + + // Step 3.2. + return result.succeed(); + } + + // Step 4. + return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("set")); +} + +/* static */ +bool MaybeCrossOriginObjectMixins::EnsureHolder( + JSContext* cx, JS::Handle obj, size_t slot, + JSPropertySpec* attributes, JSFunctionSpec* methods, + JS::MutableHandle holder) { + MOZ_ASSERT(!IsPlatformObjectSameOrigin(cx, obj) || IsRemoteObjectProxy(obj), + "Why are we calling this at all in same-origin cases?"); + // We store the holders in a weakmap stored in obj's slot. Our object is + // always a proxy, so we can just go ahead and use GetProxyReservedSlot here. + JS::Rooted weakMapVal(cx, js::GetProxyReservedSlot(obj, slot)); + if (weakMapVal.isUndefined()) { + // Enter the Realm of "obj" when we allocate the WeakMap, since we are going + // to store it in a slot on "obj" and in general we may not be + // same-compartment with "obj" here. + JSAutoRealm ar(cx, obj); + JSObject* newMap = JS::NewWeakMapObject(cx); + if (!newMap) { + return false; + } + weakMapVal.setObject(*newMap); + js::SetProxyReservedSlot(obj, slot, weakMapVal); + } + MOZ_ASSERT(weakMapVal.isObject(), + "How did a non-object else end up in this slot?"); + + JS::Rooted map(cx, &weakMapVal.toObject()); + MOZ_ASSERT(JS::IsWeakMapObject(map), + "How did something else end up in this slot?"); + + // We need to be in "map"'s compartment to work with it. Per spec, the key + // for this map is supposed to be the pair (current settings, relevant + // settings). The current settings corresponds to the current Realm of cx. + // The relevant settings corresponds to the Realm of "obj", but since all of + // our objects are per-Realm singletons, we are basically using "obj" itself + // as part of the key. + // + // To represent the current settings, we use the current-Realm + // Object.prototype. We can't use the current global, because we can't get a + // useful cross-compartment wrapper for it; such wrappers would always go + // through a WindowProxy and would not be guarantee to keep pointing to a + // single Realm when unwrapped. We want to grab this key before we start + // changing Realms. + JS::Rooted key(cx, JS::GetRealmObjectPrototype(cx)); + if (!key) { + return false; + } + + JS::Rooted holderVal(cx); + { // Scope for working with the map + JSAutoRealm ar(cx, map); + if (!MaybeWrapObject(cx, &key)) { + return false; + } + + if (!JS::GetWeakMapEntry(cx, map, key, &holderVal)) { + return false; + } + } + + if (holderVal.isObject()) { + // We want to do an unchecked unwrap, because the holder (and the current + // caller) may actually be more privileged than our map. + holder.set(js::UncheckedUnwrap(&holderVal.toObject())); + + // holder might be a dead object proxy if things got nuked. + if (!JS_IsDeadWrapper(holder)) { + MOZ_ASSERT(js::GetContextRealm(cx) == js::GetNonCCWObjectRealm(holder), + "How did we end up with a key/value mismatch?"); + return true; + } + } + + // We didn't find a usable holder. Go ahead and allocate one. At this point + // we have two options: we could allocate the holder in the current Realm and + // store a cross-compartment wrapper for it in the map as needed, or we could + // allocate the holder in the Realm of the map and have it hold + // cross-compartment references to all the methods it holds, since those + // methods need to be in our current Realm. It seems better to allocate the + // holder in our current Realm. + holder.set(JS_NewObjectWithGivenProto(cx, nullptr, nullptr)); + if (!holder || !JS_DefineProperties(cx, holder, attributes) || + !JS_DefineFunctions(cx, holder, methods)) { + return false; + } + + holderVal.setObject(*holder); + { // Scope for working with the map + JSAutoRealm ar(cx, map); + + // Key is already in the right Realm, but we need to wrap the value. + if (!MaybeWrapValue(cx, &holderVal)) { + return false; + } + + if (!JS::SetWeakMapEntry(cx, map, key, holderVal)) { + return false; + } + } + + return true; +} + +/* static */ +bool MaybeCrossOriginObjectMixins::ReportCrossOriginDenial( + JSContext* aCx, JS::Handle aId, const nsACString& aAccessType) { + xpc::AccessCheck::reportCrossOriginDenial(aCx, aId, aAccessType); + return false; +} + +template +bool MaybeCrossOriginObject::getPrototype( + JSContext* cx, JS::Handle proxy, + JS::MutableHandle protop) const { + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + protop.set(nullptr); + return true; + } + + { // Scope for JSAutoRealm + JSAutoRealm ar(cx, proxy); + protop.set(getSameOriginPrototype(cx)); + if (!protop) { + return false; + } + } + + return MaybeWrapObject(cx, protop); +} + +template +bool MaybeCrossOriginObject::setPrototype( + JSContext* cx, JS::Handle proxy, JS::Handle proto, + JS::ObjectOpResult& result) const { + // Inlined version of + // https://tc39.github.io/ecma262/#sec-set-immutable-prototype + js::AssertSameCompartment(cx, proto); + + // We have to be careful how we get the prototype. In particular, we do _NOT_ + // want to enter the Realm of "proxy" to do that, in case we're not + // same-origin with it here. + JS::Rooted wrappedProxy(cx, proxy); + if (!MaybeWrapObject(cx, &wrappedProxy)) { + return false; + } + + JS::Rooted currentProto(cx); + if (!js::GetObjectProto(cx, wrappedProxy, ¤tProto)) { + return false; + } + + if (currentProto != proto) { + return result.failCantSetProto(); + } + + return result.succeed(); +} + +template +bool MaybeCrossOriginObject::getPrototypeIfOrdinary( + JSContext* cx, JS::Handle proxy, bool* isOrdinary, + JS::MutableHandle protop) const { + // We have a custom [[GetPrototypeOf]] + *isOrdinary = false; + return true; +} + +template +bool MaybeCrossOriginObject::isExtensible(JSContext* cx, + JS::Handle proxy, + bool* extensible) const { + // We never allow [[PreventExtensions]] to succeed. + *extensible = true; + return true; +} + +template +bool MaybeCrossOriginObject::preventExtensions( + JSContext* cx, JS::Handle proxy, + JS::ObjectOpResult& result) const { + return result.failCantPreventExtensions(); +} + +template +bool MaybeCrossOriginObject::defineProperty( + JSContext* cx, JS::Handle proxy, JS::Handle id, + JS::Handle desc, JS::ObjectOpResult& result) const { + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("define")); + } + + // Enter the Realm of proxy and do the remaining work in there. + JSAutoRealm ar(cx, proxy); + JS::Rooted descCopy(cx, desc); + if (!JS_WrapPropertyDescriptor(cx, &descCopy)) { + return false; + } + + JS_MarkCrossZoneId(cx, id); + + return definePropertySameOrigin(cx, proxy, id, descCopy, result); +} + +template +JSObject* MaybeCrossOriginObject::enumerate( + JSContext* cx, JS::Handle proxy) const { + // We want to avoid any possible magic here and just do the BaseProxyHandler + // thing of using our property keys to enumerate. + // + // Note that we do not need to enter the Realm of "proxy" here, nor do we want + // to: if this is a cross-origin access we want to handle it appropriately. + return js::BaseProxyHandler::enumerate(cx, proxy); +} + +} // namespace dom +} // namespace mozilla diff --git a/dom/base/MaybeCrossOriginObject.h b/dom/base/MaybeCrossOriginObject.h new file mode 100644 index 000000000000..2597e9817a64 --- /dev/null +++ b/dom/base/MaybeCrossOriginObject.h @@ -0,0 +1,325 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_dom_MaybeCrossOriginObject_h +#define mozilla_dom_MaybeCrossOriginObject_h + +/** + * Shared infrastructure for WindowProxy and Location objects. These + * are the objects that can be accessed cross-origin in the HTML + * specification. + * + * This class can be inherited from by the relevant proxy handlers to + * help implement spec algorithms. + * + * The algorithms this class implements come from + * , + * , + * and + * . + * + * The class is templated on its base so we can directly implement the things + * that should have identical implementations for WindowProxy and Location. The + * templating is needed because WindowProxy needs to be a wrapper and Location + * shouldn't be one. + */ + +#include "js/Class.h" +#include "js/TypeDecls.h" +#include "nsStringFwd.h" + +namespace mozilla { +namespace dom { + +// Methods that MaybeCrossOriginObject wants that do not depend on the "Base" +// template parameter. We can avoid having multiple instantiations of them by +// pulling them out into this helper class. +class MaybeCrossOriginObjectMixins { + protected: + /** + * Implementation of + * . + * "cx" and "obj" may or may not be same-compartment and even when + * same-compartment may not be same-Realm. "obj" can be a WindowProxy, a + * Window, or a Location. + */ + static bool IsPlatformObjectSameOrigin(JSContext* cx, + JS::Handle obj); + + /** + * Implementation of + * . + * + * "cx" and "obj" are expected to be different-Realm here, and may be + * different-compartment. "obj" can be a "WindowProxy" or a "Location" or a + * cross-process proxy for one of those. + */ + bool CrossOriginGetOwnPropertyHelper( + JSContext* cx, JS::Handle obj, JS::Handle id, + JS::MutableHandle desc) const; + + /** + * Implementation of + * . + * + * This should be called at the end of getOwnPropertyDescriptor + * methods in the cross-origin case. + * + * "cx" and "obj" are expected to be different-Realm here, and may + * be different-compartment. "obj" can be a "WindowProxy" or a + * "Location" or a cross-process proxy for one of those. + */ + static bool CrossOriginPropertyFallback( + JSContext* cx, JS::Handle obj, JS::Handle id, + JS::MutableHandle desc); + + /** + * Implementation of + * . + * + * "cx" and "obj" are expected to be different-Realm here and may be + * different-compartment. "obj" can be a "WindowProxy" or a + * "Location" or a cross-process proxy for one of those. + * + * "receiver" will be in the compartment of "cx". The return value will + * be in the compartment of "cx". + */ + static bool CrossOriginGet(JSContext* cx, JS::Handle obj, + JS::Handle receiver, + JS::Handle id, + JS::MutableHandle vp); + + /** + * Implementation of + * . + * + * "cx" and "obj" are expected to be different-Realm here and may be + * different-compartment. "obj" can be a "WindowProxy" or a + * "Location" or a cross-process proxy for one of those. + * + * "receiver" and "v" will be in the compartment of "cx". + */ + static bool CrossOriginSet(JSContext* cx, JS::Handle obj, + JS::Handle id, JS::Handle v, + JS::Handle receiver, + JS::ObjectOpResult& result); + + /** + * Utility method to ensure a holder for cross-origin properties for the + * current global of the JSContext. + * + * When this is called, "cx" and "obj" are _always_ different-Realm, because + * this is only used in cross-origin situations. The "holder" return value is + * always in the Realm of "cx". + * + * "obj" is the object which has space to store the collection of holders in + * the given slot. + * + * "attributes" and "methods" are the cross-origin attributes and methods we + * care about, which should get defined on holders. + */ + static bool EnsureHolder(JSContext* cx, JS::Handle obj, + size_t slot, JSPropertySpec* attributes, + JSFunctionSpec* methods, + JS::MutableHandle holder); + + /** + * Ensures we have a holder object for the current Realm. When this is + * called, "obj" is guaranteed to not be same-Realm with "cx", because this + * is only used for cross-origin cases. + * + * Subclasses are expected to implement this by calling our static + * EnsureHolder with the appropriate arguments. + */ + virtual bool EnsureHolder(JSContext* cx, JS::Handle proxy, + JS::MutableHandle holder) const = 0; + + /** + * Report a cross-origin denial for a property named by aId. Always + * returns false, so it can be used as "return + * ReportCrossOriginDenial(...);". + */ + static bool ReportCrossOriginDenial(JSContext* aCx, JS::Handle aId, + const nsACString& aAccessType); +}; + +// A proxy handler for objects that may be cross-origin objects. Whether they +// actually _are_ cross-origin objects can change dynamically if document.domain +// is set. +template +class MaybeCrossOriginObject : public Base, + public MaybeCrossOriginObjectMixins { + protected: + template + constexpr MaybeCrossOriginObject(Args&&... aArgs) + : Base(std::forward(aArgs)...) {} + + /** + * Implementation of [[GetPrototypeOf]] as defined in + * + * and + * . + * + * Our prototype-storage model looks quite different from the spec's, so we + * need to implement some hooks that don't directly map to the spec. + * + * "proxy" is the WindowProxy or Location involved. It may or may not be + * same-compartment with cx. + * + * "protop" is the prototype value (possibly null). It is guaranteed to be + * same-compartment with cx after this function returns successfully. + */ + bool getPrototype(JSContext* cx, JS::Handle proxy, + JS::MutableHandle protop) const final; + + /** + * Hook for doing the OrdinaryGetPrototypeOf bits that [[GetPrototypeOf]] does + * in the spec. Location and WindowProxy store that information somewhat + * differently. + * + * The prototype should come from the Realm of "cx". + */ + virtual JSObject* getSameOriginPrototype(JSContext* cx) const = 0; + + /** + * Implementation of [[SetPrototypeOf]] as defined in + * + * and + * . + * + * "proxy" is the WindowProxy or Location object involved. It may or may not + * be same-compartment with "cx". + * + * "proto" is the new prototype object (possibly null). It must be + * same-compartment with "cx". + */ + bool setPrototype(JSContext* cx, JS::Handle proxy, + JS::Handle proto, + JS::ObjectOpResult& result) const final; + + /** + * Our non-standard getPrototypeIfOrdinary hook. We don't need to implement + * setImmutablePrototype, because the default behavior of not allowing it is + * fine for us. + */ + bool getPrototypeIfOrdinary(JSContext* cx, JS::Handle proxy, + bool* isOrdinary, + JS::MutableHandle protop) const final; + + /** + * Implementation of [[IsExtensible]] as defined in + * + * and + * . + */ + bool isExtensible(JSContext* cx, JS::Handle proxy, + bool* extensible) const final; + + /** + * Implementation of [[PreventExtensions]] as defined in + * + * and + * . + */ + bool preventExtensions(JSContext* cx, JS::Handle proxy, + JS::ObjectOpResult& result) const final; + + /** + * Implementation of [[GetOwnProperty]] is completely delegated to subclasses. + * + * "proxy" is the WindowProxy or Location object involved. It may or may not + * be same-compartment with cx. + */ + bool getOwnPropertyDescriptor( + JSContext* cx, JS::Handle proxy, JS::Handle id, + JS::MutableHandle desc) const override = 0; + + /** + * Implementation of [[DefineOwnProperty]] as defined in + * + * and + * . + * "proxy" is the WindowProxy or Location object involved. It may or may not + * be same-compartment with cx. + * + */ + bool defineProperty(JSContext* cx, JS::Handle proxy, + JS::Handle id, + JS::Handle desc, + JS::ObjectOpResult& result) const final; + + /** + * Hook for handling the same-origin case in defineProperty. + * + * "proxy" is the WindowProxy or Location object involved. It will be + * same-compartment with cx. + * + * "desc" is a the descriptor being defined. It will be same-compartment with + * cx. + */ + virtual bool definePropertySameOrigin(JSContext* cx, + JS::Handle proxy, + JS::Handle id, + JS::Handle desc, + JS::ObjectOpResult& result) const = 0; + + /** + * Implementation of [[Get]] is completely delegated to subclasses. + * + * "proxy" is the WindowProxy or Location object involved. It may or may not + * be same-compartment with "cx". + * + * "receiver" is the receiver ("this") for the get. It will be + * same-compartment with "cx" + * + * "vp" is the return value. It will be same-compartment with "cx". + */ + bool get(JSContext* cx, JS::Handle proxy, + JS::Handle receiver, JS::Handle id, + JS::MutableHandle vp) const override = 0; + + /** + * Implementation of [[Set]] is completely delegated to subclasses. + * + * "proxy" is the WindowProxy or Location object involved. It may or may not + * be same-compartment with "cx". + * + * "v" is the value being set. It will be same-compartment with "cx". + * + * "receiver" is the receiver ("this") for the set. It will be + * same-compartment with "cx". + */ + bool set(JSContext* cx, JS::Handle proxy, JS::Handle id, + JS::Handle v, JS::Handle receiver, + JS::ObjectOpResult& result) const override = 0; + + /** + * Implementation of [[Delete]] is completely delegated to subclasses. + * + * "proxy" is the WindowProxy or Location object involved. It may or may not + * be same-compartment with "cx". + */ + bool delete_(JSContext* cx, JS::Handle proxy, JS::Handle id, + JS::ObjectOpResult& result) const override = 0; + + /** + * Spidermonkey-internal hook for enumerating objects. + */ + JSObject* enumerate(JSContext* cx, JS::Handle proxy) const final; + + /** + * Spidermonkey-internal hook used by Object.prototype.toString. Subclasses + * need to implement this, because we don't know what className they want. + * Except in the cross-origin case, when we could maybe handle it... + */ + const char* className(JSContext* cx, + JS::Handle proxy) const override = 0; +}; + +} // namespace dom +} // namespace mozilla + +#endif /* mozilla_dom_MaybeCrossOriginObject_h */ diff --git a/dom/base/RemoteOuterWindowProxy.cpp b/dom/base/RemoteOuterWindowProxy.cpp index 0f8effcbe253..d690253b2cae 100644 --- a/dom/base/RemoteOuterWindowProxy.cpp +++ b/dom/base/RemoteOuterWindowProxy.cpp @@ -121,8 +121,7 @@ bool RemoteOuterWindowProxy::getOwnPropertyDescriptor( return ReportCrossOriginDenial(aCx, aId, NS_LITERAL_CSTRING("access")); } - bool ok = RemoteObjectProxy::getOwnPropertyDescriptorInternal(aCx, aProxy, - aId, aDesc); + bool ok = CrossOriginGetOwnPropertyHelper(aCx, aProxy, aId, aDesc); if (!ok || aDesc.object()) { return ok; } @@ -140,7 +139,7 @@ bool RemoteOuterWindowProxy::getOwnPropertyDescriptor( } } - return getOwnPropertyDescriptorTail(aCx, aProxy, aId, aDesc); + return CrossOriginPropertyFallback(aCx, aProxy, aId, aDesc); } bool AppendIndexedPropertyNames(JSContext* aCx, BrowsingContext* aContext, diff --git a/dom/base/moz.build b/dom/base/moz.build index 160e5c8aa3f0..8cbd77df31e4 100644 --- a/dom/base/moz.build +++ b/dom/base/moz.build @@ -193,6 +193,7 @@ EXPORTS.mozilla.dom += [ 'IntlUtils.h', 'Link.h', 'Location.h', + 'MaybeCrossOriginObject.h', 'MessageBroadcaster.h', 'MessageListenerManager.h', 'MessageManagerGlobal.h', @@ -298,6 +299,7 @@ UNIFIED_SOURCES += [ 'IntlUtils.cpp', 'Link.cpp', 'Location.cpp', + 'MaybeCrossOriginObject.cpp', 'MessageBroadcaster.cpp', 'MessageListenerManager.cpp', 'MessageManagerGlobal.cpp', diff --git a/dom/bindings/RemoteObjectProxy.cpp b/dom/bindings/RemoteObjectProxy.cpp index d0dc38fe1250..5dbc2a9d726b 100644 --- a/dom/bindings/RemoteObjectProxy.cpp +++ b/dom/bindings/RemoteObjectProxy.cpp @@ -20,12 +20,12 @@ const js::Class RemoteObjectProxyClass = bool RemoteObjectProxyBase::getOwnPropertyDescriptor( JSContext* aCx, JS::Handle aProxy, JS::Handle aId, JS::MutableHandle aDesc) const { - bool ok = getOwnPropertyDescriptorInternal(aCx, aProxy, aId, aDesc); + bool ok = CrossOriginGetOwnPropertyHelper(aCx, aProxy, aId, aDesc); if (!ok || aDesc.object()) { return ok; } - return getOwnPropertyDescriptorTail(aCx, aProxy, aId, aDesc); + return CrossOriginPropertyFallback(aCx, aProxy, aId, aDesc); } bool RemoteObjectProxyBase::defineProperty( @@ -137,24 +137,7 @@ bool RemoteObjectProxyBase::get(JSContext* aCx, JS::Handle aProxy, JS::Handle aReceiver, JS::Handle aId, JS::MutableHandle aVp) const { - Rooted desc(aCx); - if (!getOwnPropertyDescriptor(aCx, aProxy, aId, &desc)) { - return false; - } - - MOZ_ASSERT(desc.object()); - - if (desc.isDataDescriptor()) { - aVp.set(desc.value()); - return true; - } - - JS::Rooted getter(aCx); - if (!desc.hasGetterObject() || !(getter = desc.getterObject())) { - return ReportCrossOriginDenial(aCx, aId, NS_LITERAL_CSTRING("get")); - } - - return JS::Call(aCx, aReceiver, getter, JS::HandleValueArray::empty(), aVp); + return CrossOriginGet(aCx, aProxy, aReceiver, aId, aVp); } bool RemoteObjectProxyBase::set(JSContext* aCx, JS::Handle aProxy, @@ -162,21 +145,7 @@ bool RemoteObjectProxyBase::set(JSContext* aCx, JS::Handle aProxy, JS::Handle aValue, JS::Handle aReceiver, JS::ObjectOpResult& aResult) const { - Rooted desc(aCx); - if (!getOwnPropertyDescriptor(aCx, aProxy, aId, &desc)) { - return false; - } - - MOZ_ASSERT(desc.object()); - - JS::Rooted setter(aCx); - if (!desc.hasSetterObject() || !(setter = desc.setterObject())) { - return ReportCrossOriginDenial(aCx, aId, NS_LITERAL_CSTRING("set")); - } - - JS::Rooted rv(aCx); - return JS::Call(aCx, aReceiver, setter, JS::HandleValueArray(aValue), &rv) && - aResult.succeed(); + return CrossOriginSet(aCx, aProxy, aId, aValue, aReceiver, aResult); } bool RemoteObjectProxyBase::hasOwn(JSContext* aCx, JS::Handle aProxy, @@ -208,32 +177,6 @@ JSObject* RemoteObjectProxyBase::CreateProxyObject( return js::NewProxyObject(aCx, this, native, nullptr, options); } -/* static */ -bool RemoteObjectProxyBase::getOwnPropertyDescriptorTail( - JSContext* aCx, JS::Handle aProxy, JS::Handle aId, - JS::MutableHandle aDesc) { - if (xpc::IsCrossOriginWhitelistedProp(aCx, aId)) { - // https://html.spec.whatwg.org/multipage/browsers.html#crossorigingetownpropertyhelper-(-o,-p-) - // step 3 says to return PropertyDescriptor { - // [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, - // [[Configurable]]: true - // }. - // - aDesc.setDataDescriptor(JS::UndefinedHandleValue, JSPROP_READONLY); - aDesc.object().set(aProxy); - return true; - } - - return ReportCrossOriginDenial(aCx, aId, NS_LITERAL_CSTRING("access")); -} - -/* static */ -bool RemoteObjectProxyBase::ReportCrossOriginDenial( - JSContext* aCx, JS::Handle aId, const nsACString& aAccessType) { - xpc::AccessCheck::reportCrossOriginDenial(aCx, aId, aAccessType); - return false; -} - const char RemoteObjectProxyBase::sCrossOriginProxyFamily = 0; } // namespace dom diff --git a/dom/bindings/RemoteObjectProxy.h b/dom/bindings/RemoteObjectProxy.h index 14bfc3f822cd..a076ac1eceed 100644 --- a/dom/bindings/RemoteObjectProxy.h +++ b/dom/bindings/RemoteObjectProxy.h @@ -8,6 +8,7 @@ #define mozilla_dom_RemoteObjectProxy_h #include "js/Proxy.h" +#include "mozilla/dom/MaybeCrossOriginObject.h" #include "mozilla/dom/PrototypeList.h" #include "xpcpublic.h" @@ -19,7 +20,8 @@ namespace dom { * don't depend on properties/methods of the specific WebIDL interface that this * proxy implements. */ -class RemoteObjectProxyBase : public js::BaseProxyHandler { +class RemoteObjectProxyBase : public js::BaseProxyHandler, + public MaybeCrossOriginObjectMixins { protected: explicit constexpr RemoteObjectProxyBase(prototypes::ID aPrototypeID) : BaseProxyHandler(&sCrossOriginProxyFamily, false), @@ -77,8 +79,9 @@ class RemoteObjectProxyBase : public js::BaseProxyHandler { } /** - * Returns true if aProxy represents an object implementing the WebIDL - * interface for aProtoID. aProxy should be a proxy object. + * Returns true if aProxy is a cross-process proxy that represents + * an object implementing the WebIDL interface for aProtoID. aProxy + * should be a proxy object. */ static inline bool IsRemoteObjectProxy(JSObject* aProxy, prototypes::ID aProtoID) { @@ -88,62 +91,19 @@ class RemoteObjectProxyBase : public js::BaseProxyHandler { aProtoID; } - protected: - bool getOwnPropertyDescriptorInternal( - JSContext* aCx, JS::Handle aProxy, JS::Handle aId, - JS::MutableHandle aDesc) const { - JS::Rooted holder(aCx); - if (!EnsureHolder(aCx, aProxy, &holder) || - !JS_GetOwnPropertyDescriptorById(aCx, holder, aId, aDesc)) { - return false; - } - - if (aDesc.object()) { - aDesc.object().set(aProxy); - } - - return true; + /** + * Returns true if aProxy is a cross-process proxy, no matter which + * interface it represents. aProxy should be a proxy object. + */ + static inline bool IsRemoteObjectProxy(JSObject* aProxy) { + const js::BaseProxyHandler* handler = js::GetProxyHandler(aProxy); + return handler->family() == &sCrossOriginProxyFamily; } + protected: JSObject* CreateProxyObject(JSContext* aCx, void* aNative, const js::Class* aClasp) const; - /** - * Implements the tail of getOwnPropertyDescriptor, dealing in particular with - * properties that are whitelisted by xpc::IsCrossOriginWhitelistedProp. - */ - static bool getOwnPropertyDescriptorTail( - JSContext* aCx, JS::Handle aProxy, JS::Handle aId, - JS::MutableHandle aDesc); - static bool ReportCrossOriginDenial(JSContext* aCx, JS::Handle aId, - const nsACString& aAccessType); - - /** - * This gets a cached, or creates and caches, a holder object that contains - * the WebIDL properties for this proxy. - */ - bool EnsureHolder(JSContext* aCx, JS::Handle aProxy, - JS::MutableHandle aHolder) const { - // FIXME Need to have a holder per realm, should store a weakmap in the - // reserved slot. - JS::Value v = js::GetProxyReservedSlot(aProxy, 0); - if (v.isObject()) { - aHolder.set(&v.toObject()); - return true; - } - - aHolder.set(JS_NewObjectWithGivenProto(aCx, nullptr, nullptr)); - if (!aHolder || !DefinePropertiesAndFunctions(aCx, aHolder)) { - return false; - } - - js::SetProxyReservedSlot(aProxy, 0, JS::ObjectValue(*aHolder)); - return true; - } - - virtual bool DefinePropertiesAndFunctions( - JSContext* aCx, JS::Handle aHolder) const = 0; - const prototypes::ID mPrototypeID; static const char sCrossOriginProxyFamily; @@ -175,16 +135,17 @@ class RemoteObjectProxy : public RemoteObjectProxyBase { using RemoteObjectProxyBase::RemoteObjectProxyBase; private: - bool DefinePropertiesAndFunctions(JSContext* aCx, - JS::Handle aHolder) const final { - return JS_DefineProperties(aCx, aHolder, P) && - JS_DefineFunctions(aCx, aHolder, F); + bool EnsureHolder(JSContext* aCx, JS::Handle aProxy, + JS::MutableHandle aHolder) const final { + return MaybeCrossOriginObjectMixins::EnsureHolder( + aCx, aProxy, /* slot = */ 0, P, F, aHolder); } }; /** - * Returns true if aObj is a proxy object that represents an object implementing - * the WebIDL interface for aProtoID. + * Returns true if aObj is a cross-process proxy object that + * represents an object implementing the WebIDL interface for + * aProtoID. */ static inline bool IsRemoteObjectProxy(JSObject* aObj, prototypes::ID aProtoID) { @@ -194,6 +155,17 @@ static inline bool IsRemoteObjectProxy(JSObject* aObj, return RemoteObjectProxyBase::IsRemoteObjectProxy(aObj, aProtoID); } +/** + * Returns true if aObj is a cross-process proxy object, no matter + * which WebIDL interface it corresponds to. + */ +static inline bool IsRemoteObjectProxy(JSObject* aObj) { + if (!js::IsProxy(aObj)) { + return false; + } + return RemoteObjectProxyBase::IsRemoteObjectProxy(aObj); +} + } // namespace dom } // namespace mozilla From f699207ace3116bdce0aa2ac1dbb3bd115dacc85 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:28:55 +0000 Subject: [PATCH 06/33] Bug 1363208 part 3. Change nsOuterWindowProxy to inherit from MaybeCrossOriginObject. r=peterv,jandem The cross-origin named window code in nsOuterWindowProxy::getOwnPropertyDescriptor is mostly copied from XrayWrapper::getPropertyDescriptor, with some minor changes because we can't assume some work that CrossOriginXrayWrapper does. The getPropertyDescriptor version will go away in a later patch in this stack. Differential Revision: https://phabricator.services.mozilla.com/D15427 --HG-- extra : moz-landing-system : lando --- dom/base/MaybeCrossOriginObject.cpp | 3 + dom/base/nsGlobalWindowOuter.cpp | 503 ++++++++++++++++++++++------ 2 files changed, 404 insertions(+), 102 deletions(-) diff --git a/dom/base/MaybeCrossOriginObject.cpp b/dom/base/MaybeCrossOriginObject.cpp index 327310893f68..477ea96d96c0 100644 --- a/dom/base/MaybeCrossOriginObject.cpp +++ b/dom/base/MaybeCrossOriginObject.cpp @@ -429,5 +429,8 @@ JSObject* MaybeCrossOriginObject::enumerate( return js::BaseProxyHandler::enumerate(cx, proxy); } +// Force instantiations of the out-of-line template methods we need. +template class MaybeCrossOriginObject; + } // namespace dom } // namespace mozilla diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index e5a6dfbd935a..d95d83c892a1 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -30,6 +30,7 @@ #include "mozilla/dom/LSObject.h" #include "mozilla/dom/Storage.h" #include "mozilla/dom/IdleRequest.h" +#include "mozilla/dom/MaybeCrossOriginObject.h" #include "mozilla/dom/Performance.h" #include "mozilla/dom/StorageEvent.h" #include "mozilla/dom/StorageEventBinding.h" @@ -340,54 +341,165 @@ nsPIDOMWindowOuter* nsPIDOMWindowOuter::GetFromCurrentInner( // nsOuterWindowProxy: Outer Window Proxy //***************************************************************************** -class nsOuterWindowProxy : public js::Wrapper { +// Give OuterWindowProxyClass 2 reserved slots, like the other wrappers, so +// JSObject::swap can swap it with CrossCompartmentWrappers without requiring +// malloc. +// +// We store the nsGlobalWindowOuter* in our first slot. +// +// We store our holder weakmap in the second slot. +const js::Class OuterWindowProxyClass = PROXY_CLASS_DEF( + "Proxy", JSCLASS_HAS_RESERVED_SLOTS(2)); /* additional class flags */ + +static const size_t OUTER_WINDOW_SLOT = 0; +static const size_t HOLDER_WEAKMAP_SLOT = 1; + +class nsOuterWindowProxy : public MaybeCrossOriginObject { + typedef MaybeCrossOriginObject Base; + public: - constexpr nsOuterWindowProxy() : js::Wrapper(0) {} + constexpr nsOuterWindowProxy() : Base(0) {} bool finalizeInBackground(const JS::Value& priv) const override { return false; } // Standard internal methods + /** + * Implementation of [[GetOwnProperty]] as defined at + * https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-getownproperty + * + * "proxy" is the WindowProxy object involved. It may not be same-compartment + * with cx. + */ bool getOwnPropertyDescriptor( JSContext* cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc) const override; - bool defineProperty(JSContext* cx, JS::Handle proxy, - JS::Handle id, - JS::Handle desc, - JS::ObjectOpResult& result) const override; + + /* + * Implementation of the same-origin case of + * . + */ + bool definePropertySameOrigin(JSContext* cx, JS::Handle proxy, + JS::Handle id, + JS::Handle desc, + JS::ObjectOpResult& result) const override; + + /** + * Implementation of [[OwnPropertyKeys]] as defined at + * + * https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-ownpropertykeys + * + * "proxy" is the WindowProxy object involved. It may not be same-compartment + * with cx. + */ bool ownPropertyKeys(JSContext* cx, JS::Handle proxy, JS::AutoIdVector& props) const override; + /** + * Implementation of [[Delete]] as defined at + * https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-delete + * + * "proxy" is the WindowProxy object involved. It may not be same-compartment + * with cx. + */ bool delete_(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::ObjectOpResult& result) const override; - bool getPrototypeIfOrdinary( - JSContext* cx, JS::Handle proxy, bool* isOrdinary, - JS::MutableHandle protop) const override; + /** + * Implementaton of hook for superclass getPrototype() method. + */ + JSObject* getSameOriginPrototype(JSContext* cx) const override; - JSObject* enumerate(JSContext* cx, - JS::Handle proxy) const override; - bool preventExtensions(JSContext* cx, JS::Handle proxy, - JS::ObjectOpResult& result) const override; - bool isExtensible(JSContext* cx, JS::Handle proxy, - bool* extensible) const override; + /** + * Implementation of [[HasProperty]] internal method as defined at + * https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-hasproperty-p + * + * "proxy" is the WindowProxy object involved. It may not be same-compartment + * with cx. + * + * Note that the HTML spec does not define an override for this internal + * method, so we just want the "normal object" behavior. We have to override + * it, because js::Wrapper also overrides, with "not normal" behavior. + */ bool has(JSContext* cx, JS::Handle proxy, JS::Handle id, bool* bp) const override; + + /** + * Implementation of [[Get]] internal method as defined at + * . + * + * "proxy" is the WindowProxy object involved. It may or may not be + * same-compartment with "cx". + * + * "receiver" is the receiver ("this") for the get. It will be + * same-compartment with "cx". + * + * "vp" is the return value. It will be same-compartment with "cx". + */ bool get(JSContext* cx, JS::Handle proxy, JS::Handle receiver, JS::Handle id, JS::MutableHandle vp) const override; + + /** + * Implementation of [[Set]] internal method as defined at + * . + * + * "proxy" is the WindowProxy object involved. It may or may not be + * same-compartment with "cx". + * + * "v" is the value being set. It will be same-compartment with "cx". + * + * "receiver" is the receiver ("this") for the set. It will be + * same-compartment with "cx". + */ bool set(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::Handle v, JS::Handle receiver, JS::ObjectOpResult& result) const override; // SpiderMonkey extensions + /** + * Non-standard method we want to get rid of. + * + * "proxy" is the WindowProxy object involved. It may not be same-compartment + * with cx. + * + * The only reason we implement this is because js::Wrapper does and we want + * different behavior from the js::Wrapper implementation. + */ bool getPropertyDescriptor( JSContext* cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc) const override; + + /** + * Implementation of SpiderMonkey extension which just checks whether this + * object has the property. Basically Object.getOwnPropertyDescriptor(obj, + * prop) !== undefined. but does not require reifying the descriptor. + * + * We have to override this because js::Wrapper overrides it, but we want + * different behavior from js::Wrapper. + * + * "proxy" is the WindowProxy object involved. It may not be same-compartment + * with cx. + */ bool hasOwn(JSContext* cx, JS::Handle proxy, JS::Handle id, bool* bp) const override; + + /** + * Implementation of SpiderMonkey extension which is used as a fast path for + * enumerating. + * + * We have to override this because js::Wrapper overrides it, but we want + * different behavior from js::Wrapper. + * + * "proxy" is the WindowProxy object involved. It may not be same-compartment + * with cx. + */ bool getOwnEnumerablePropertyKeys(JSContext* cx, JS::Handle proxy, JS::AutoIdVector& props) const override; + + /** + * Hook used by SpiderMonkey to implement Object.prototype.toString. + */ const char* className(JSContext* cx, JS::Handle wrapper) const override; @@ -403,7 +515,7 @@ class nsOuterWindowProxy : public js::Wrapper { static nsGlobalWindowOuter* GetOuterWindow(JSObject* proxy) { nsGlobalWindowOuter* outerWindow = nsGlobalWindowOuter::FromSupports(static_cast( - js::GetProxyReservedSlot(proxy, 0).toPrivate())); + js::GetProxyReservedSlot(proxy, OUTER_WINDOW_SLOT).toPrivate())); return outerWindow; } @@ -418,20 +530,22 @@ class nsOuterWindowProxy : public js::Wrapper { already_AddRefed GetSubframeWindow( JSContext* cx, JS::Handle proxy, JS::Handle id) const; - bool AppendIndexedPropertyNames(JSContext* cx, JSObject* proxy, + bool AppendIndexedPropertyNames(JSObject* proxy, JS::AutoIdVector& props) const; -}; -// Give OuterWindowProxyClass 2 reserved slots, like the other wrappers, so -// JSObject::swap can swap it with CrossCompartmentWrappers without requiring -// malloc. -const js::Class OuterWindowProxyClass = PROXY_CLASS_DEF( - "Proxy", JSCLASS_HAS_RESERVED_SLOTS(2)); /* additional class flags */ + using MaybeCrossOriginObjectMixins::EnsureHolder; + bool EnsureHolder(JSContext* cx, JS::Handle proxy, + JS::MutableHandle holder) const override; +}; const char* nsOuterWindowProxy::className(JSContext* cx, JS::Handle proxy) const { MOZ_ASSERT(js::IsProxy(proxy)); + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return "Object"; + } + return "Window"; } @@ -455,9 +569,13 @@ void nsOuterWindowProxy::finalize(JSFreeOp* fop, JSObject* proxy) const { bool nsOuterWindowProxy::getPropertyDescriptor( JSContext* cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc) const { - // The only thing we can do differently from js::Wrapper is shadow stuff with - // our indexed properties, so we can just try getOwnPropertyDescriptor and if - // that gives us nothing call on through to js::Wrapper. + // In the same-origin case the only thing we can do differently from + // js::Wrapper is shadow stuff with our indexed properties, so we can just try + // getOwnPropertyDescriptor and if that gives us nothing call on through to + // js::Wrapper. + // + // In the cross-origin case, we can only have own properties, so don't even + // need to worry about the js::Proxy bit. desc.object().set(nullptr); if (!getOwnPropertyDescriptor(cx, proxy, id, desc)) { return false; @@ -467,7 +585,22 @@ bool nsOuterWindowProxy::getPropertyDescriptor( return true; } - return js::Wrapper::getPropertyDescriptor(cx, proxy, id, desc); + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return true; + } + + // When forwarding to js::Wrapper, we should just enter the Realm of proxy + // for now. That's what js::Wrapper expects, and since we're same-origin + // anyway this is not changing any security behavior. + { + JSAutoRealm ar(cx, proxy); + JS_MarkCrossZoneId(cx, id); + if (!js::Wrapper::getPropertyDescriptor(cx, proxy, id, desc)) { + return false; + } + } + + return JS_WrapPropertyDescriptor(cx, desc); } /** @@ -495,35 +628,95 @@ static bool IsNonConfigurableReadonlyPrimitiveGlobalProp(JSContext* cx, bool nsOuterWindowProxy::getOwnPropertyDescriptor( JSContext* cx, JS::Handle proxy, JS::Handle id, JS::MutableHandle desc) const { + // First check for indexed access. This is + // https://html.spec.whatwg.org/multipage/window-object.html#windowproxy-getownproperty + // step 2, mostly. bool found; if (!GetSubframeWindow(cx, proxy, id, desc.value(), found)) { return false; } if (found) { + // Step 2.4. FillPropertyDescriptor(desc, proxy, true); return true; } - // else fall through to js::Wrapper - bool ok = js::Wrapper::getOwnPropertyDescriptor(cx, proxy, id, desc); - if (!ok) { + bool isSameOrigin = IsPlatformObjectSameOrigin(cx, proxy); + + // If we did not find a subframe, we could still have an indexed property + // access. In that case we should throw a SecurityError in the cross-origin + // case. + if (!isSameOrigin && IsArrayIndex(GetArrayIndexFromId(id))) { + // Step 2.5.2. + return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("access")); + } + + // Step 2.5.1 is handled via the forwarding to js::Wrapper; it saves us an + // IsArrayIndex(GetArrayIndexFromId(id)) here. We'll never have a property on + // the Window whose name is an index, because our defineProperty doesn't pass + // those on to the Window. + + // Step 3. + if (isSameOrigin) { + // Fall through to js::Wrapper. + { // Scope for JSAutoRealm while we are dealing with js::Wrapper. + // When forwarding to js::Wrapper, we should just enter the Realm of proxy + // for now. That's what js::Wrapper expects, and since we're same-origin + // anyway this is not changing any security behavior. + JSAutoRealm ar(cx, proxy); + JS_MarkCrossZoneId(cx, id); + bool ok = js::Wrapper::getOwnPropertyDescriptor(cx, proxy, id, desc); + if (!ok) { + return false; + } + +#ifndef RELEASE_OR_BETA // To be turned on in bug 1496510. + if (!IsNonConfigurableReadonlyPrimitiveGlobalProp(cx, id)) { + desc.setConfigurable(true); + } +#endif + } + + // Now wrap our descriptor back into the Realm that asked for it. + return JS_WrapPropertyDescriptor(cx, desc); + } + + // Step 4. + if (!CrossOriginGetOwnPropertyHelper(cx, proxy, id, desc)) { return false; } -#ifndef RELEASE_OR_BETA // To be turned on in bug 1496510. - if (!IsNonConfigurableReadonlyPrimitiveGlobalProp(cx, id)) { - desc.setConfigurable(true); + // Step 5 + if (desc.object()) { + return true; } -#endif - return true; + // Step 6 -- check for named subframes. + if (JSID_IS_STRING(id)) { + nsAutoJSString name; + if (!name.init(cx, JSID_TO_STRING(id))) { + return false; + } + nsGlobalWindowOuter* win = GetOuterWindow(proxy); + if (RefPtr childDOMWin = win->GetChildWindow(name)) { + JS::Rooted childValue(cx); + if (!ToJSValue(cx, WindowProxyHolder(childDOMWin), &childValue)) { + return false; + } + FillPropertyDescriptor(desc, proxy, childValue, + /* readonly = */ true, + /* enumerable = */ false); + return true; + } + } + + // And step 7. + return CrossOriginPropertyFallback(cx, proxy, id, desc); } -bool nsOuterWindowProxy::defineProperty(JSContext* cx, - JS::Handle proxy, - JS::Handle id, - JS::Handle desc, - JS::ObjectOpResult& result) const { +bool nsOuterWindowProxy::definePropertySameOrigin( + JSContext* cx, JS::Handle proxy, JS::Handle id, + JS::Handle desc, JS::ObjectOpResult& result) const { if (IsArrayIndex(GetArrayIndexFromId(id))) { // Spec says to Reject whether this is a supported index or not, // since we have no indexed setter or indexed creator. It is up @@ -599,20 +792,52 @@ bool nsOuterWindowProxy::ownPropertyKeys(JSContext* cx, JS::Handle proxy, JS::AutoIdVector& props) const { // Just our indexed stuff followed by our "normal" own property names. - if (!AppendIndexedPropertyNames(cx, proxy, props)) { + if (!AppendIndexedPropertyNames(proxy, props)) { return false; } - JS::AutoIdVector innerProps(cx); - if (!js::Wrapper::ownPropertyKeys(cx, proxy, innerProps)) { + if (IsPlatformObjectSameOrigin(cx, proxy)) { + // When forwarding to js::Wrapper, we should just enter the Realm of proxy + // for now. That's what js::Wrapper expects, and since we're same-origin + // anyway this is not changing any security behavior. + JS::AutoIdVector innerProps(cx); + { // Scope for JSAutoRealm so we can mark the ids once we exit it + JSAutoRealm ar(cx, proxy); + if (!js::Wrapper::ownPropertyKeys(cx, proxy, innerProps)) { + return false; + } + } + for (auto& id : innerProps) { + JS_MarkCrossZoneId(cx, id); + } + return js::AppendUnique(cx, props, innerProps); + } + + // In the cross-origin case we purposefully exclude subframe names from the + // list of property names we report here. + JS::Rooted holder(cx); + if (!EnsureHolder(cx, proxy, &holder)) { return false; } - return js::AppendUnique(cx, props, innerProps); + + JS::AutoIdVector crossOriginProps(cx); + if (!js::GetPropertyKeys(cx, holder, + JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, + &crossOriginProps) || + !js::AppendUnique(cx, props, crossOriginProps)) { + return false; + } + + return xpc::AppendCrossOriginWhitelistedPropNames(cx, props); } bool nsOuterWindowProxy::delete_(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::ObjectOpResult& result) const { + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete")); + } + if (nsCOMPtr frame = GetSubframeWindow(cx, proxy, id)) { // Fail (which means throw if strict, else return false). return result.failCantDeleteWindowElement(); @@ -623,62 +848,72 @@ bool nsOuterWindowProxy::delete_(JSContext* cx, JS::Handle proxy, return result.succeed(); } + // We're same-origin, so it should be safe to enter the Realm of "proxy". + // Let's do that, just in case, to avoid cross-compartment issues in our + // js::Wrapper caller.. + JSAutoRealm ar(cx, proxy); + JS_MarkCrossZoneId(cx, id); return js::Wrapper::delete_(cx, proxy, id, result); } -bool nsOuterWindowProxy::getPrototypeIfOrdinary( - JSContext* cx, JS::Handle proxy, bool* isOrdinary, - JS::MutableHandle protop) const { - // Window's [[GetPrototypeOf]] trap isn't the ordinary definition: - // - // https://html.spec.whatwg.org/multipage/browsers.html#windowproxy-getprototypeof - // - // We nonetheless can implement it with a static [[Prototype]], because - // wrapper-class handlers (particularly, XOW in FilteringWrapper.cpp) supply - // all non-ordinary behavior. - // - // But from a spec point of view, it's the exact same object in both cases -- - // only the observer's changed. So this getPrototypeIfOrdinary trap on the - // non-wrapper object *must* report non-ordinary, even if static [[Prototype]] - // usually means ordinary. - *isOrdinary = false; - return true; -} - -bool nsOuterWindowProxy::preventExtensions(JSContext* cx, - JS::Handle proxy, - JS::ObjectOpResult& result) const { - // If [[Extensible]] could be false, then navigating a window could navigate - // to a window that's [[Extensible]] after being at one that wasn't: an - // invariant violation. So never change a window's extensibility. - return result.failCantPreventExtensions(); -} - -bool nsOuterWindowProxy::isExtensible(JSContext* cx, - JS::Handle proxy, - bool* extensible) const { - // See above. - *extensible = true; - return true; +JSObject* nsOuterWindowProxy::getSameOriginPrototype(JSContext* cx) const { + return Window_Binding::GetProtoObjectHandle(cx); } bool nsOuterWindowProxy::has(JSContext* cx, JS::Handle proxy, JS::Handle id, bool* bp) const { + // We could just directly forward this method to js::BaseProxyHandler, but + // that involves reifying the actual property descriptor, which might be more + // work than we have to do for has() on the Window. + + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + // In the cross-origin case we only have own properties. Just call hasOwn + // directly. + return hasOwn(cx, proxy, id, bp); + } + if (nsCOMPtr frame = GetSubframeWindow(cx, proxy, id)) { *bp = true; return true; } + // Just to be safe in terms of compartment asserts, enter the Realm of + // "proxy". We're same-origin with it, so this should be safe. + JSAutoRealm ar(cx, proxy); + JS_MarkCrossZoneId(cx, id); return js::Wrapper::has(cx, proxy, id, bp); } bool nsOuterWindowProxy::hasOwn(JSContext* cx, JS::Handle proxy, JS::Handle id, bool* bp) const { + // We could just directly forward this method to js::BaseProxyHandler, but + // that involves reifying the actual property descriptor, which might be more + // work than we have to do for hasOwn() on the Window. + + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + // Avoiding reifying the property descriptor here would require duplicating + // a bunch of "is this property exposed cross-origin" logic, which is + // probably not worth it. Just forward this along to the base + // implementation. + // + // It's very important to not forward this to js::Wrapper, because that will + // not do the right security and cross-origin checks and will pass through + // the call to the Window. + // + // The BaseProxyHandler code is OK with this happening without entering the + // compartment of "proxy". + return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp); + } + if (nsCOMPtr frame = GetSubframeWindow(cx, proxy, id)) { *bp = true; return true; } + // Just to be safe in terms of compartment asserts, enter the Realm of + // "proxy". We're same-origin with it, so this should be safe. + JSAutoRealm ar(cx, proxy); + JS_MarkCrossZoneId(cx, id); return js::Wrapper::hasOwn(cx, proxy, id, bp); } @@ -689,58 +924,110 @@ bool nsOuterWindowProxy::get(JSContext* cx, JS::Handle proxy, if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_WRAPPED_JSOBJECT) && xpc::AccessCheck::isChrome(js::GetContextCompartment(cx))) { vp.set(JS::ObjectValue(*proxy)); - return true; + return MaybeWrapValue(cx, vp); + } + + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return CrossOriginGet(cx, proxy, receiver, id, vp); } bool found; if (!GetSubframeWindow(cx, proxy, id, vp, found)) { return false; } + if (found) { return true; } - // Else fall through to js::Wrapper - return js::Wrapper::get(cx, proxy, receiver, id, vp); + { // Scope for JSAutoRealm + // Enter "proxy"'s Realm. We're in the same-origin case, so this should be + // safe. + JSAutoRealm ar(cx, proxy); + + JS_MarkCrossZoneId(cx, id); + + JS::Rooted wrappedReceiver(cx, receiver); + if (!MaybeWrapValue(cx, &wrappedReceiver)) { + return false; + } + + // Fall through to js::Wrapper. + if (!js::Wrapper::get(cx, proxy, wrappedReceiver, id, vp)) { + return false; + } + } + + // Make sure our return value is in the caller compartment. + return MaybeWrapValue(cx, vp); } bool nsOuterWindowProxy::set(JSContext* cx, JS::Handle proxy, JS::Handle id, JS::Handle v, JS::Handle receiver, JS::ObjectOpResult& result) const { + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return CrossOriginSet(cx, proxy, id, v, receiver, result); + } + if (IsArrayIndex(GetArrayIndexFromId(id))) { // Reject the set. It's up to the caller to decide whether to throw a // TypeError. If the caller is strict mode JS code, it'll throw. return result.failReadOnly(); } - return js::Wrapper::set(cx, proxy, id, v, receiver, result); + // Do the rest in the Realm of "proxy", since we're in the same-origin case. + JSAutoRealm ar(cx, proxy); + JS::Rooted wrappedArg(cx, v); + if (!MaybeWrapValue(cx, &wrappedArg)) { + return false; + } + JS::Rooted wrappedReceiver(cx, receiver); + if (!MaybeWrapValue(cx, &wrappedReceiver)) { + return false; + } + + JS_MarkCrossZoneId(cx, id); + + return js::Wrapper::set(cx, proxy, id, wrappedArg, wrappedReceiver, result); } bool nsOuterWindowProxy::getOwnEnumerablePropertyKeys( JSContext* cx, JS::Handle proxy, JS::AutoIdVector& props) const { + // We could just stop overring getOwnEnumerablePropertyKeys and let our + // superclasses deal (by falling back on the BaseProxyHandler implementation + // that uses a combination of ownPropertyKeys and getOwnPropertyDescriptor to + // only return the enumerable ones. But maybe there's value in having + // somewhat faster for-in iteration on Window objects... + // Like ownPropertyKeys, our indexed stuff followed by our "normal" enumerable // own property names. - // - // Note that this does not match current spec per - // https://github.com/whatwg/html/issues/2753 but as that issue says I believe - // the spec is wrong. - if (!AppendIndexedPropertyNames(cx, proxy, props)) { + if (!AppendIndexedPropertyNames(proxy, props)) { return false; } + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + // All the cross-origin properties other than the indexed props are + // non-enumerable, so we're done here. + return true; + } + + // When forwarding to js::Wrapper, we should just enter the Realm of proxy + // for now. That's what js::Wrapper expects, and since we're same-origin + // anyway this is not changing any security behavior. JS::AutoIdVector innerProps(cx); - if (!js::Wrapper::getOwnEnumerablePropertyKeys(cx, proxy, innerProps)) { - return false; + { // Scope for JSAutoRealm so we can mark the ids once we exit it. + JSAutoRealm ar(cx, proxy); + if (!js::Wrapper::getOwnEnumerablePropertyKeys(cx, proxy, innerProps)) { + return false; + } } - return js::AppendUnique(cx, props, innerProps); -} -JSObject* nsOuterWindowProxy::enumerate(JSContext* cx, - JS::Handle proxy) const { - // BaseProxyHandler::enumerate seems to do what we want here: fall - // back on the property names returned from js::GetPropertyKeys() - return js::BaseProxyHandler::enumerate(cx, proxy); + for (auto& id : innerProps) { + JS_MarkCrossZoneId(cx, id); + } + + return js::AppendUnique(cx, props, innerProps); } bool nsOuterWindowProxy::GetSubframeWindow(JSContext* cx, @@ -782,7 +1069,7 @@ already_AddRefed nsOuterWindowProxy::GetSubframeWindow( } bool nsOuterWindowProxy::AppendIndexedPropertyNames( - JSContext* cx, JSObject* proxy, JS::AutoIdVector& props) const { + JSObject* proxy, JS::AutoIdVector& props) const { uint32_t length = GetOuterWindow(proxy)->Length(); MOZ_ASSERT(int32_t(length) >= 0); if (!props.reserve(props.length() + length)) { @@ -797,6 +1084,14 @@ bool nsOuterWindowProxy::AppendIndexedPropertyNames( return true; } +bool nsOuterWindowProxy::EnsureHolder( + JSContext* cx, JS::Handle proxy, + JS::MutableHandle holder) const { + return EnsureHolder(cx, proxy, HOLDER_WEAKMAP_SLOT, + Window_Binding::sCrossOriginAttributes, + Window_Binding::sCrossOriginMethods, holder); +} + size_t nsOuterWindowProxy::objectMoved(JSObject* obj, JSObject* old) const { nsGlobalWindowOuter* outerWindow = GetOuterWindow(obj); if (outerWindow) { @@ -986,7 +1281,8 @@ nsGlobalWindowOuter::~nsGlobalWindowOuter() { if (mBrowsingContext) { mBrowsingContext->ClearWindowProxy(); } - js::SetProxyReservedSlot(proxy, 0, js::PrivateValue(nullptr)); + js::SetProxyReservedSlot(proxy, OUTER_WINDOW_SLOT, + js::PrivateValue(nullptr)); } // An outer window is destroyed with inner windows still possibly @@ -1813,7 +2109,8 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, cx, NewOuterWindowProxy(cx, newInnerGlobal, thisChrome)); NS_ENSURE_TRUE(outer, NS_ERROR_FAILURE); - js::SetProxyReservedSlot(outer, 0, js::PrivateValue(ToSupports(this))); + js::SetProxyReservedSlot(outer, OUTER_WINDOW_SLOT, + js::PrivateValue(ToSupports(this))); // Inform the nsJSContext, which is the canonical holder of the outer. mContext->SetWindowProxy(outer); @@ -1831,8 +2128,10 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, JS::Rooted obj(cx, GetWrapperPreserveColor()); - js::SetProxyReservedSlot(obj, 0, js::PrivateValue(nullptr)); - js::SetProxyReservedSlot(outerObject, 0, js::PrivateValue(nullptr)); + js::SetProxyReservedSlot(obj, OUTER_WINDOW_SLOT, + js::PrivateValue(nullptr)); + js::SetProxyReservedSlot(outerObject, OUTER_WINDOW_SLOT, + js::PrivateValue(nullptr)); outerObject = xpc::TransplantObject(cx, obj, outerObject); if (!outerObject) { @@ -1841,7 +2140,7 @@ nsresult nsGlobalWindowOuter::SetNewDocument(Document* aDocument, return NS_ERROR_FAILURE; } - js::SetProxyReservedSlot(outerObject, 0, + js::SetProxyReservedSlot(outerObject, OUTER_WINDOW_SLOT, js::PrivateValue(ToSupports(this))); SetWrapper(outerObject); From c17e30f6b2673ba646d45936bdcbf88e1d41086e Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:30:31 +0000 Subject: [PATCH 07/33] Bug 1363208 part 4. Stop using cross-origin Xrays for WindowProxy. r=peterv,jandem The change to test_bug440572.html is due to a behavior change. Specifically, before this change, any IDL-declared property, even one not exposed cross-origin, would prevent named frames with that name being visible cross-origin. The new behavior is that cross-origin-exposed IDL properties prevent corresponding frame names from being visible, but ones not exposed cross-origin don't. This matches the spec and other browsers. Same thing for the changes to test_bug860494.xul. The wpt test changes are just adding test coverage for the thing the other tests caught. Differential Revision: https://phabricator.services.mozilla.com/D15428 --HG-- extra : moz-landing-system : lando --- dom/bindings/BindingUtils.cpp | 2 +- dom/tests/mochitest/bugs/test_bug440572.html | 10 ++++-- js/xpconnect/tests/chrome/test_bug860494.xul | 4 +-- js/xpconnect/wrappers/WrapperFactory.cpp | 9 ++++- js/xpconnect/wrappers/WrapperFactory.h | 36 +++++++++++++++++++ .../cross-origin-objects.html | 24 +++++++++++++ .../cross-origin-objects/frame-with-then.html | 4 +++ 7 files changed, 83 insertions(+), 6 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 6b0302018be4..e4a8ecf6dd85 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -2903,7 +2903,7 @@ struct CrossOriginThisPolicy : public MaybeGlobalThisPolicy { // We want the ExtractThisObject of MaybeGlobalThisPolicy. static MOZ_ALWAYS_INLINE JSObject* MaybeUnwrapThisObject(JSObject* aObj) { - if (xpc::WrapperFactory::IsXrayWrapper(aObj)) { + if (xpc::WrapperFactory::IsCrossOriginWrapper(aObj)) { return js::UncheckedUnwrap(aObj); } diff --git a/dom/tests/mochitest/bugs/test_bug440572.html b/dom/tests/mochitest/bugs/test_bug440572.html index fe8f92d3d349..d4d309356929 100644 --- a/dom/tests/mochitest/bugs/test_bug440572.html +++ b/dom/tests/mochitest/bugs/test_bug440572.html @@ -27,9 +27,11 @@ window.addEventListener("message", receiveMessage); function runtests() { - is(messages.size, 2, "received the right number of messages."); + is(messages.size, 4, "received the right number of messages."); is(messages.get("test"), "success", "test in frame failed."); - isnot(messages.get("dump"), "success", "parent[\"dump\"] should be the WebIDL property of Window."); + is(messages.get("dump"), "success", '"dump" in frame failed.'); + is(messages.get("open"), "success", '"open" in frame failed.'); + isnot(messages.get("close"), "success", "parent[\"close\"] should be the WebIDL property of Window."); SimpleTest.finish(); } @@ -40,6 +42,10 @@ SimpleTest.waitForExplicitFinish();
+
+ +
+ diff --git a/js/xpconnect/tests/chrome/test_bug860494.xul b/js/xpconnect/tests/chrome/test_bug860494.xul index bab31eaf3822..5d5ac825a8ef 100644 --- a/js/xpconnect/tests/chrome/test_bug860494.xul +++ b/js/xpconnect/tests/chrome/test_bug860494.xul @@ -44,8 +44,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=860494 Cu.evalInSandbox('ok(win.parent === parentWin, "iframe names shouldnt shadow |parent| via cross-origin Xray");', sb); Cu.evalInSandbox('is(win.length, 7, "iframe names shouldnt shadow |length| via cross-origin Xray");', sb); Cu.evalInSandbox('ok(win.window === win, "iframe names shouldnt shadow |window| via cross-origin Xray");', sb); - Cu.evalInSandbox('var exn = "nothrow"; try { win.navigator; } catch (e) { exn = e; } ok(!!/denied/.exec(exn), "cross-origin Xray blocks subframes that shadow: navigator: " + exn);', sb); - Cu.evalInSandbox('var exn = "nothrow"; try { win.alert; } catch (e) { exn = e; } ok(!!/denied/.exec(exn), "cross-origin Xray blocks subframes that shadow: alert: " + exn);', sb); + Cu.evalInSandbox('ok(win.navigator === win[5], "iframe names that correspond to non-cross-origin-visible properties should expose the subframe: navigator");', sb); + Cu.evalInSandbox('ok(win.alert === win[6], "iframe names that correspond to non-cross-origin-visible properties should expose the subframe: alert");', sb); SimpleTest.finish(); } diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index 50267417707f..caddde1195e6 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -361,6 +361,8 @@ static void DEBUG_CheckUnwrapSafety(HandleObject obj, {} #endif +const CrossOriginObjectWrapper CrossOriginObjectWrapper::singleton; + static const Wrapper* SelectWrapper(bool securityWrapper, XrayType xrayType, bool waiveXrays, JSObject* obj) { // Waived Xray uses a modified CCW that has transparent behavior but @@ -394,11 +396,16 @@ static const Wrapper* SelectWrapper(bool securityWrapper, XrayType xrayType, // This is a security wrapper. Use the security versions and filter. if (xrayType == XrayForDOMObject && - IdentifyCrossOriginObject(obj) != CrossOriginOpaque) { + IdentifyCrossOriginObject(obj) == CrossOriginLocation) { return &FilteringWrapper::singleton; } + if (xrayType == XrayForDOMObject && + IdentifyCrossOriginObject(obj) == CrossOriginWindow) { + return &CrossOriginObjectWrapper::singleton; + } + // There's never any reason to expose other objects to non-subsuming actors. // Just use an opaque wrapper in these cases. // diff --git a/js/xpconnect/wrappers/WrapperFactory.h b/js/xpconnect/wrappers/WrapperFactory.h index 73bf43b1cce8..ad0ac49ea356 100644 --- a/js/xpconnect/wrappers/WrapperFactory.h +++ b/js/xpconnect/wrappers/WrapperFactory.h @@ -11,6 +11,36 @@ namespace xpc { +/** + * A wrapper that's only used for cross-origin objects. This should be + * just like a CrossCompartmentWrapper but (as an implementation + * detail) doesn't actually do any compartment-entering and (as an + * implementation detail) delegates all the security decisions and + * compartment-entering to the target object, which is always a + * proxy. + * + * We could also inherit from CrossCompartmentWrapper but then we + * would need to override all the proxy hooks to avoid the + * compartment-entering bits. + */ +class CrossOriginObjectWrapper : public js::Wrapper { + public: + // We want to claim to have a security policy, so code doesn't just + // CheckedUnwrap us willy-nilly. But we're OK with the BaseProxyHandler + // implementation of enter(), which allows entering. Our target is what + // really does the security checks. + // + // We don't want to inherit from CrossCompartmentWrapper, because we don't + // want the compartment-entering behavior it has. But we do want to set the + // CROSS_COMPARTMENT flag on js::Wrapper so that we test true for + // is and so forth. + constexpr explicit CrossOriginObjectWrapper() + : js::Wrapper(CROSS_COMPARTMENT, /* aHasPrototype = */ false, + /* aHasSecurityPolicy = */ true) {} + + static const CrossOriginObjectWrapper singleton; +}; + class WrapperFactory { public: enum { @@ -29,6 +59,12 @@ class WrapperFactory { return HasWrapperFlag(wrapper, IS_XRAY_WRAPPER_FLAG); } + static bool IsCrossOriginWrapper(JSObject* obj) { + return IsXrayWrapper(obj) || + (js::IsProxy(obj) && + js::GetProxyHandler(obj) == &CrossOriginObjectWrapper::singleton); + } + static bool HasWaiveXrayFlag(JSObject* wrapper) { return HasWrapperFlag(wrapper, WAIVE_XRAY_WRAPPER_FLAG); } diff --git a/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html b/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html index caac56a176de..918293836188 100644 --- a/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html +++ b/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html @@ -150,11 +150,22 @@ addTest(function() { assert_throws(new TypeError, function() { protoSetter.call(C, new Object()); }, "proto setter |call| on cross-origin Window"); assert_throws(new TypeError, function() { protoSetter.call(C.location, new Object()); }, "proto setter |call| on cross-origin Location"); }); + // Hack to avoid "duplicate test name" harness issues. + setters.forEach(function(protoSetter) { + test(function() { protoSetter.call(C, null); }, + "proto setter |call| on cross-origin Window with null (" + protoSetter + ")"); + test(function() { protoSetter.call(C.location, null); }, + "proto setter |call| on cross-origin Location with null (" + protoSetter + ")"); + }); if (Reflect.setPrototypeOf) { assert_false(Reflect.setPrototypeOf(C, new Object()), "Reflect.setPrototypeOf on cross-origin Window"); + assert_true(Reflect.setPrototypeOf(C, null), + "Reflect.setPrototypeOf on cross-origin Window with null"); assert_false(Reflect.setPrototypeOf(C.location, new Object()), "Reflect.setPrototypeOf on cross-origin Location"); + assert_true(Reflect.setPrototypeOf(C.location, null), + "Reflect.setPrototypeOf on cross-origin Location with null"); } }, "[[SetPrototypeOf]] should return false"); @@ -230,6 +241,19 @@ addTest(function() { assert_equals(typeof D.then, "object"); }, "[[GetOwnProperty]] - Subframe named 'then' should shadow the default 'then' value"); +addTest(function() { + assert_equals(typeof D.close, "function"); + assert_equals(typeof D.open, "object"); +}, "[[GetOwnProperty]] - Subframes should be visible cross-origin only if their names don't match the names of cross-origin-exposed IDL properties"); + +addTest(function() { + assert_equals(typeof Object.getOwnPropertyDescriptor(C, '0').value, "object"); + assert_equals(typeof Object.getOwnPropertyDescriptor(C, '1').value, "object"); + assert_throws("SecurityError", function() { + Object.getOwnPropertyDescriptor(C, '2'); + }); +}, "[[GetOwnProperty]] - Should be able to get a property descriptor for an indexed property only if it corresponds to a child window."); + /* * [[Delete]] */ diff --git a/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/frame-with-then.html b/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/frame-with-then.html index 96cdf1ea99b1..1127995ea84d 100644 --- a/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/frame-with-then.html +++ b/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/frame-with-then.html @@ -6,5 +6,9 @@ + + + From abd3e90089dada2f4865f9e9b262eb447db5f6f9 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:33:14 +0000 Subject: [PATCH 08/33] Bug 1363208 part 5. Remove now-unnecessary named subframe handling from XrayWrapper. r=peterv Differential Revision: https://phabricator.services.mozilla.com/D15429 --HG-- extra : moz-landing-system : lando --- js/xpconnect/wrappers/XrayWrapper.cpp | 32 --------------------------- 1 file changed, 32 deletions(-) diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index 1c07d7b5af17..d7edefd3fcde 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1912,39 +1912,7 @@ bool XrayWrapper::getPropertyDescriptor( } if (desc.object()) { desc.object().set(wrapper); - return true; } - - // We need to handle named access on the Window somewhere other than - // Traits::resolveOwnProperty, because per spec it happens on the Global - // Scope Polluter and thus the resulting properties are non-|own|. However, - // we're set up (above) to cache (on the holder), - // which we don't want for something dynamic like named access. - // So we just handle it separately here. Note that this is - // only relevant for CrossOriginXrayWrapper, which calls - // getPropertyDescriptor from getOwnPropertyDescriptor. - nsGlobalWindowInner* win = nullptr; - if (!desc.object() && JSID_IS_STRING(id) && (win = AsWindow(cx, wrapper))) { - nsAutoJSString name; - if (!name.init(cx, JSID_TO_STRING(id))) { - return false; - } - RefPtr childDOMWin(win->GetChildWindow(name)); - if (childDOMWin) { - auto* cwin = nsGlobalWindowOuter::Cast(childDOMWin->GetDOMWindow()); - JSObject* childObj = cwin->FastGetGlobalJSObject(); - if (MOZ_UNLIKELY(!childObj)) { - return xpc::Throw(cx, NS_ERROR_FAILURE); - } - ExposeObjectToActiveJS(childObj); - FillPropertyDescriptor(desc, wrapper, ObjectValue(*childObj), - /* readOnly = */ true); - return JS_WrapPropertyDescriptor(cx, desc); - } - } - - // We found nothing, we're done. - MOZ_ASSERT(!desc.object()); return true; } From 4dffd37187bb45fa41e0f8503c7013e82c15dd15 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:33:16 +0000 Subject: [PATCH 09/33] Bug 1363208 part 6. Remove the NonOrdinaryGetPrototypeOf annotation. r=peterv We can just check for a non-global object (so excluding Window) with cross-origin properties. Differential Revision: https://phabricator.services.mozilla.com/D15430 --HG-- extra : moz-landing-system : lando --- dom/bindings/Codegen.py | 6 +++--- dom/bindings/Configuration.py | 17 ++++++++++++++--- dom/bindings/parser/WebIDL.py | 3 +-- dom/webidl/Location.webidl | 2 +- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index d6dc577dccee..ea2bc128cad1 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -3758,7 +3758,7 @@ def InitMemberSlots(descriptor, failureCode): def SetImmutablePrototype(descriptor, failureCode): - if not descriptor.hasNonOrdinaryGetPrototypeOf(): + if not descriptor.isMaybeCrossOriginObject(): return "" return fill( @@ -12522,7 +12522,7 @@ class CGDOMJSProxyHandler(CGClass): def __init__(self, descriptor): assert (descriptor.supportsIndexedProperties() or descriptor.supportsNamedProperties() or - descriptor.hasNonOrdinaryGetPrototypeOf()) + descriptor.isMaybeCrossOriginObject()) methods = [CGDOMJSProxyHandler_getOwnPropDescriptor(descriptor), CGDOMJSProxyHandler_defineProperty(descriptor), ClassUsingDeclaration("mozilla::dom::DOMProxyHandler", @@ -12549,7 +12549,7 @@ class CGDOMJSProxyHandler(CGClass): (descriptor.operations['NamedSetter'] is not None and descriptor.interface.getExtendedAttribute('OverrideBuiltins'))): methods.append(CGDOMJSProxyHandler_setCustom(descriptor)) - if descriptor.hasNonOrdinaryGetPrototypeOf(): + if descriptor.isMaybeCrossOriginObject(): methods.append(CGDOMJSProxyHandler_getPrototypeIfOrdinary()) if descriptor.operations['LegacyCaller']: methods.append(CGDOMJSProxyHandler_call()) diff --git a/dom/bindings/Configuration.py b/dom/bindings/Configuration.py index ae088415f831..f1e46d1bb1f8 100644 --- a/dom/bindings/Configuration.py +++ b/dom/bindings/Configuration.py @@ -442,6 +442,7 @@ class Descriptor(DescriptorProvider): if self.concrete: self.proxy = False + self.hasCrossOriginMembers = False iface = self.interface for m in iface.members: # Don't worry about inheriting legacycallers either: in @@ -456,9 +457,17 @@ class Descriptor(DescriptorProvider): addOperation('LegacyCaller', m) while iface: for m in iface.members: + if (m.isAttr() and + (m.getExtendedAttribute("CrossOriginReadable") or + m.getExtendedAttribute("CrossOriginWritable"))): + self.hasCrossOriginMembers = True + if not m.isMethod(): continue + if m.getExtendedAttribute("CrossOriginCallable"): + self.hasCrossOriginMembers = True + def addIndexedOrNamedOperation(operation, m): if m.isIndexed(): operation = 'Indexed' + operation @@ -484,7 +493,7 @@ class Descriptor(DescriptorProvider): self.proxy = (self.supportsIndexedProperties() or (self.supportsNamedProperties() and not self.hasNamedPropertiesObject) or - self.hasNonOrdinaryGetPrototypeOf()) + self.isMaybeCrossOriginObject()) if self.proxy: if (not self.operations['IndexedGetter'] and @@ -708,8 +717,10 @@ class Descriptor(DescriptorProvider): namedGetter = self.operations['NamedGetter'] return namedGetter.getExtendedAttribute("NeedsCallerType") - def hasNonOrdinaryGetPrototypeOf(self): - return self.interface.getExtendedAttribute("NonOrdinaryGetPrototypeOf") + def isMaybeCrossOriginObject(self): + # If we're isGlobal and have cross-origin members, we're a Window, and + # that's not a cross-origin object. The WindowProxy is. + return self.hasCrossOriginMembers and not self.isGlobal() def needsHeaderInclude(self): """ diff --git a/dom/bindings/parser/WebIDL.py b/dom/bindings/parser/WebIDL.py index 7377a468e748..9cf60ee840c8 100644 --- a/dom/bindings/parser/WebIDL.py +++ b/dom/bindings/parser/WebIDL.py @@ -1786,8 +1786,7 @@ class IDLInterface(IDLInterfaceOrNamespace): identifier == "ProbablyShortLivingWrapper" or identifier == "LegacyUnenumerableNamedProperties" or identifier == "RunConstructorInCallerCompartment" or - identifier == "WantsEventListenerHooks" or - identifier == "NonOrdinaryGetPrototypeOf"): + identifier == "WantsEventListenerHooks"): # Known extended attributes that do not take values if not attr.noArguments(): raise WebIDLError("[%s] must take no arguments" % identifier, diff --git a/dom/webidl/Location.webidl b/dom/webidl/Location.webidl index b802d32b5cc3..07fb6076d5b8 100644 --- a/dom/webidl/Location.webidl +++ b/dom/webidl/Location.webidl @@ -11,7 +11,7 @@ * and create derivative works of this document. */ -[Unforgeable, NonOrdinaryGetPrototypeOf] +[Unforgeable] interface Location { // Bug 824857: no support for stringifier attributes yet. // stringifier attribute USVString href; From 46d5d31b591cf925aa1a2e79513ca45cd8533532 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 04:26:13 +0000 Subject: [PATCH 10/33] Bug 1363208 part 7. Change the Location binding to inherit from MaybeCrossOriginObject. r=peterv Differential Revision: https://phabricator.services.mozilla.com/D15431 --HG-- extra : moz-landing-system : lando --- dom/base/MaybeCrossOriginObject.cpp | 2 + dom/base/MaybeCrossOriginObject.h | 7 + dom/bindings/BindingUtils.h | 6 +- dom/bindings/Codegen.py | 539 ++++++++++++++++++++++++---- dom/bindings/Configuration.py | 10 + 5 files changed, 484 insertions(+), 80 deletions(-) diff --git a/dom/base/MaybeCrossOriginObject.cpp b/dom/base/MaybeCrossOriginObject.cpp index 477ea96d96c0..311da11a41fb 100644 --- a/dom/base/MaybeCrossOriginObject.cpp +++ b/dom/base/MaybeCrossOriginObject.cpp @@ -8,6 +8,7 @@ #include "mozilla/BasePrincipal.h" #include "mozilla/dom/BindingUtils.h" +#include "mozilla/dom/DOMJSProxyHandler.h" #include "mozilla/dom/RemoteObjectProxy.h" #include "js/Proxy.h" #include "js/RootingAPI.h" @@ -431,6 +432,7 @@ JSObject* MaybeCrossOriginObject::enumerate( // Force instantiations of the out-of-line template methods we need. template class MaybeCrossOriginObject; +template class MaybeCrossOriginObject; } // namespace dom } // namespace mozilla diff --git a/dom/base/MaybeCrossOriginObject.h b/dom/base/MaybeCrossOriginObject.h index 2597e9817a64..95f6e17799ef 100644 --- a/dom/base/MaybeCrossOriginObject.h +++ b/dom/base/MaybeCrossOriginObject.h @@ -251,6 +251,13 @@ class MaybeCrossOriginObject : public Base, JS::Handle desc, JS::ObjectOpResult& result) const final; + /** + * Some of our base classes define _another_ virtual defineProperty, and we + * get overloaded-virtual warnings as a result due to us hiding it, if we + * don't pull it in here. + */ + using Base::defineProperty; + /** * Hook for handling the same-origin case in defineProperty. * diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 27f536029deb..5b97ec529934 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -2496,11 +2496,13 @@ class MOZ_STACK_CLASS BindingJSObjectCreator { void CreateProxyObject(JSContext* aCx, const js::Class* aClass, const DOMProxyHandler* aHandler, - JS::Handle aProto, T* aNative, - JS::Handle aExpandoValue, + JS::Handle aProto, bool aLazyProto, + T* aNative, JS::Handle aExpandoValue, JS::MutableHandle aReflector) { js::ProxyOptions options; options.setClass(aClass); + options.setLazyProto(aLazyProto); + aReflector.set( js::NewProxyObject(aCx, aHandler, aExpandoValue, aProto, options)); if (aReflector) { diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index ea2bc128cad1..9b2d074fc85c 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -356,7 +356,9 @@ class CGNativePropertyHooks(CGThing): if not self.descriptor.wantsXrays: return "" deleteNamedProperty = "nullptr" - if self.descriptor.concrete and self.descriptor.proxy: + if (self.descriptor.concrete and + self.descriptor.proxy and + not self.descriptor.isMaybeCrossOriginObject()): resolveOwnProperty = "ResolveOwnProperty" enumerateOwnProperties = "EnumerateOwnProperties" if self.descriptor.needsXrayNamedDeleterHook(): @@ -445,7 +447,14 @@ def DOMClass(descriptor): def InstanceReservedSlots(descriptor): - return INSTANCE_RESERVED_SLOTS + descriptor.interface.totalMembersInSlots + slots = INSTANCE_RESERVED_SLOTS + descriptor.interface.totalMembersInSlots + if descriptor.isMaybeCrossOriginObject(): + # We need a slot for the cross-origin holder too. + if descriptor.interface.hasChildInterfaces(): + raise TypeError("We don't support non-leaf cross-origin interfaces " + "like %s" % descriptor.interface.identifier.name) + slots += 1 + return slots class CGDOMJSClass(CGThing): @@ -3582,19 +3591,30 @@ def CreateBindingJSObject(descriptor, properties): # of cases where we do, so for simplicity, just always root it. if descriptor.proxy: if descriptor.interface.getExtendedAttribute('OverrideBuiltins'): + assert not descriptor.isMaybeCrossOriginObject() create = dedent( """ aObject->mExpandoAndGeneration.expando.setUndefined(); JS::Rooted expandoValue(aCx, JS::PrivateValue(&aObject->mExpandoAndGeneration)); creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(), - proto, aObject, expandoValue, aReflector); + proto, /* aLazyProto = */ false, aObject, + expandoValue, aReflector); """) else: - create = dedent( + if descriptor.isMaybeCrossOriginObject(): + proto = "nullptr" + lazyProto = "true" + else: + proto = "proto" + lazyProto = "false" + create = fill( """ creator.CreateProxyObject(aCx, &sClass.mBase, DOMProxyHandler::getInstance(), - proto, aObject, JS::UndefinedHandleValue, aReflector); - """) + ${proto}, /* aLazyProto = */ ${lazyProto}, + aObject, JS::UndefinedHandleValue, aReflector); + """, + proto=proto, + lazyProto=lazyProto) else: create = dedent( """ @@ -3757,35 +3777,30 @@ def InitMemberSlots(descriptor, failureCode): failureCode=failureCode) -def SetImmutablePrototype(descriptor, failureCode): - if not descriptor.isMaybeCrossOriginObject(): - return "" - - return fill( - """ - bool succeeded; - if (!JS_SetImmutablePrototype(aCx, aReflector, &succeeded)) { - ${failureCode} - } - MOZ_ASSERT(succeeded, - "Making a fresh reflector instance have an immutable " - "prototype can internally fail, but it should never be " - "unsuccessful"); - """, - failureCode=failureCode) - - -def DeclareProto(): +def DeclareProto(descriptor): """ Declare the canonicalProto and proto we have for our wrapping operation. """ - return dedent( + preamble = dedent( """ JS::Handle canonicalProto = GetProtoObjectHandle(aCx); if (!canonicalProto) { return false; } JS::Rooted proto(aCx); + """) + if descriptor.isMaybeCrossOriginObject(): + return preamble + dedent( + """ + MOZ_ASSERT(!aGivenProto, + "Shouldn't have constructors on cross-origin objects"); + // Set proto to canonicalProto to avoid preserving our wrapper if + // we don't have to. + proto = canonicalProto; + """) + + return preamble + dedent( + """ if (aGivenProto) { proto = aGivenProto; // Unfortunately, while aGivenProto was in the compartment of aCx @@ -3864,7 +3879,6 @@ class CGWrapWithCacheMethod(CGAbstractMethod): aCache->SetWrapper(aReflector); $*{unforgeable} $*{slots} - $*{setImmutablePrototype} creator.InitializationSucceeded(); MOZ_ASSERT(aCache->GetWrapperPreserveColor() && @@ -3883,13 +3897,11 @@ class CGWrapWithCacheMethod(CGAbstractMethod): """, nativeType=self.descriptor.nativeType, assertInheritance=AssertInheritanceChain(self.descriptor), - declareProto=DeclareProto(), + declareProto=DeclareProto(self.descriptor), createObject=CreateBindingJSObject(self.descriptor, self.properties), unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, failureCode), - slots=InitMemberSlots(self.descriptor, failureCode), - setImmutablePrototype=SetImmutablePrototype(self.descriptor, - failureCode)) + slots=InitMemberSlots(self.descriptor, failureCode)) class CGWrapMethod(CGAbstractMethod): @@ -3943,18 +3955,15 @@ class CGWrapNonWrapperCacheMethod(CGAbstractMethod): $*{slots} - $*{setImmutablePrototype} creator.InitializationSucceeded(); return true; """, assertions=AssertInheritanceChain(self.descriptor), - declareProto=DeclareProto(), + declareProto=DeclareProto(self.descriptor), createObject=CreateBindingJSObject(self.descriptor, self.properties), unforgeable=CopyUnforgeablePropertiesToInstance(self.descriptor, failureCode), - slots=InitMemberSlots(self.descriptor, failureCode), - setImmutablePrototype=SetImmutablePrototype(self.descriptor, - failureCode)) + slots=InitMemberSlots(self.descriptor, failureCode)) class CGWrapGlobalMethod(CGAbstractMethod): @@ -11670,6 +11679,21 @@ class CGDOMJSProxyHandler_getOwnPropDescriptor(ClassMethod): indexedGetter = self.descriptor.operations['IndexedGetter'] indexedSetter = self.descriptor.operations['IndexedSetter'] + if self.descriptor.isMaybeCrossOriginObject(): + xrayDecl = dedent( + """ + MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy)); + MOZ_ASSERT(IsPlatformObjectSameOrigin(cx, proxy), + "getOwnPropertyDescriptor() and set() should have dealt"); + MOZ_ASSERT(js::IsObjectInContextCompartment(proxy, cx), + "getOwnPropertyDescriptor() and set() should have dealt"); + + """) + xrayCheck = "" + else: + xrayDecl = "bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);\n" + xrayCheck = "!isXray &&" + if self.descriptor.supportsIndexedProperties(): readonly = toStringBool(indexedSetter is None) fillDescriptor = "FillPropertyDescriptor(desc, proxy, %s);\nreturn true;\n" % readonly @@ -11744,10 +11768,10 @@ class CGDOMJSProxyHandler_getOwnPropDescriptor(ClassMethod): return fill( """ - bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy); + $*{xrayDecl} $*{getIndexed} JS::Rooted expando(cx); - if (!isXray && (expando = GetExpandoObject(proxy))) { + if (${xrayCheck}(expando = GetExpandoObject(proxy))) { if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc)) { return false; } @@ -11762,6 +11786,8 @@ class CGDOMJSProxyHandler_getOwnPropDescriptor(ClassMethod): desc.object().set(nullptr); return true; """, + xrayDecl=xrayDecl, + xrayCheck=xrayCheck, getIndexed=getIndexed, namedGet=namedGet) @@ -11848,6 +11874,14 @@ class CGDOMJSProxyHandler_defineProperty(ClassMethod): } """, presenceChecker=CGProxyNamedPresenceChecker(self.descriptor, foundVar="found").define()) + if self.descriptor.isMaybeCrossOriginObject(): + set += dedent( + """ + MOZ_ASSERT(IsPlatformObjectSameOrigin(cx, proxy), + "Why did the MaybeCrossOriginObject defineProperty override fail?"); + MOZ_ASSERT(js::IsObjectInContextCompartment(proxy, cx), + "Why did the MaybeCrossOriginObject defineProperty override fail?"); + """) set += ("return mozilla::dom::DOMProxyHandler::defineProperty(%s);\n" % ", ".join(a.name for a in self.args)) return set @@ -11959,8 +11993,22 @@ class CGDOMJSProxyHandler_delete(ClassMethod): """) + if self.descriptor.isMaybeCrossOriginObject(): + delete += dedent( + """ + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return ReportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete")); + } + + // Safe to enter the Realm of proxy now. + JSAutoRealm ar(cx, proxy); + JS_MarkCrossZoneId(cx, id); + """) + indexedBody = getDeleterBody(self.descriptor, "Indexed") if indexedBody is not None: + # Can't handle cross-origin objects here. + assert not self.descriptor.isMaybeCrossOriginObject(); delete += fill( """ uint32_t index = GetArrayIndexFromId(id); @@ -12038,6 +12086,34 @@ class CGDOMJSProxyHandler_ownPropNames(ClassMethod): self.descriptor = descriptor def getBody(self): + if self.descriptor.isMaybeCrossOriginObject(): + xrayDecl = dedent( + """ + MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy)); + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + if (!(flags & JSITER_HIDDEN)) { + // There are no enumerable cross-origin props, so we're done. + return true; + } + + JS::Rooted holder(cx); + if (!EnsureHolder(cx, proxy, &holder)) { + return false; + } + + if (!js::GetPropertyKeys(cx, holder, flags, &props)) { + return false; + } + + return xpc::AppendCrossOriginWhitelistedPropNames(cx, props); + } + + """) + xrayCheck = "" + else: + xrayDecl = "bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy);\n" + xrayCheck = "!isXray &&" + # Per spec, we do indices, then named props, then everything else. if self.descriptor.supportsIndexedProperties(): if self.descriptor.lengthNeedsCallerType(): @@ -12087,22 +12163,46 @@ class CGDOMJSProxyHandler_ownPropNames(ClassMethod): else: addNames = "" - return fill( + addExpandoProps = fill( """ - bool isXray = xpc::WrapperFactory::IsXrayWrapper(proxy); - $*{addIndices} - $*{addNames} - JS::Rooted expando(cx); - if (!isXray && (expando = DOMProxyHandler::GetExpandoObject(proxy)) && + if (${xrayCheck}(expando = DOMProxyHandler::GetExpandoObject(proxy)) && !js::GetPropertyKeys(cx, expando, flags, &props)) { return false; } + """, + xrayCheck=xrayCheck) + + if self.descriptor.isMaybeCrossOriginObject(): + # We need to enter our compartment (which we might not be + # in right now) to get the expando props. + addExpandoProps = fill( + """ + { // Scope for accessing the expando. + // Safe to enter our compartment, because IsPlatformObjectSameOrigin tested true. + JSAutoRealm ar(cx, proxy); + $*{addExpandoProps} + } + for (auto& id : props) { + JS_MarkCrossZoneId(cx, id); + } + """, + addExpandoProps=addExpandoProps) + + return fill( + """ + $*{xrayDecl} + $*{addIndices} + $*{addNames} + + $*{addExpandoProps} return true; """, + xrayDecl=xrayDecl, addIndices=addIndices, - addNames=addNames) + addNames=addNames, + addExpandoProps=addExpandoProps) class CGDOMJSProxyHandler_hasOwn(ClassMethod): @@ -12116,6 +12216,23 @@ class CGDOMJSProxyHandler_hasOwn(ClassMethod): self.descriptor = descriptor def getBody(self): + if self.descriptor.isMaybeCrossOriginObject(): + maybeCrossOrigin = dedent( + """ + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + // Just hand this off to BaseProxyHandler to do the slow-path thing. + // The BaseProxyHandler code is OK with this happening without entering the + // compartment of "proxy", which is important to get the right answers. + return js::BaseProxyHandler::hasOwn(cx, proxy, id, bp); + } + + // Now safe to enter the Realm of proxy and do the rest of the work there. + JSAutoRealm ar(cx, proxy); + JS_MarkCrossZoneId(cx, id); + """) + else: + maybeCrossOrigin = "" + if self.descriptor.supportsIndexedProperties(): indexed = fill( """ @@ -12167,7 +12284,7 @@ class CGDOMJSProxyHandler_hasOwn(ClassMethod): """ MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy), "Should not have a XrayWrapper here"); - + $*{maybeCrossOrigin} $*{indexed} JS::Rooted expando(cx, GetExpandoObject(proxy)); @@ -12183,6 +12300,7 @@ class CGDOMJSProxyHandler_hasOwn(ClassMethod): $*{named} return true; """, + maybeCrossOrigin=maybeCrossOrigin, indexed=indexed, named=named) @@ -12199,27 +12317,77 @@ class CGDOMJSProxyHandler_get(ClassMethod): self.descriptor = descriptor def getBody(self): + if self.descriptor.isMaybeCrossOriginObject(): + maybeCrossOriginGet = dedent( + """ + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return CrossOriginGet(cx, proxy, receiver, id, vp); + } + + """) + else: + maybeCrossOriginGet = "" + getUnforgeableOrExpando = dedent(""" { // Scope for expando JS::Rooted expando(cx, DOMProxyHandler::GetExpandoObject(proxy)); if (expando) { - bool hasProp; - if (!JS_HasPropertyById(cx, expando, id, &hasProp)) { + if (!JS_HasPropertyById(cx, expando, id, &expandoHasProp)) { return false; } - if (hasProp) { + if (expandoHasProp) { // Forward the get to the expando object, but our receiver is whatever our // receiver is. - return JS_ForwardGetPropertyTo(cx, expando, id, receiver, vp); + if (!JS_ForwardGetPropertyTo(cx, expando, id, rootedReceiver, vp)) { + return false; + } } } } """) + if self.descriptor.isMaybeCrossOriginObject(): + getUnforgeableOrExpando = fill( + """ + { // Scope for the JSAutoRealm accessing expando + JSAutoRealm ar(cx, proxy); + if (!MaybeWrapValue(cx, &rootedReceiver)) { + return false; + } + JS_MarkCrossZoneId(cx, id); + + $*{getUnforgeableOrExpando} + } + if (expandoHasProp) { + return MaybeWrapValue(cx, vp); + } + """, + getUnforgeableOrExpando=getUnforgeableOrExpando) + else: + getUnforgeableOrExpando = fill( + """ + $*{getUnforgeableOrExpando} + + if (expandoHasProp) { + return true; + } + """, + getUnforgeableOrExpando=getUnforgeableOrExpando) + + getUnforgeableOrExpando = fill( + """ + bool expandoHasProp = false; + $*{getUnforgeableOrExpando} + """, + getUnforgeableOrExpando=getUnforgeableOrExpando) + templateValues = {'jsvalRef': 'vp', 'jsvalHandle': 'vp', 'obj': 'proxy'} if self.descriptor.supportsIndexedProperties(): + # We can't handle this for cross-origin objects + assert not self.descriptor.isMaybeCrossOriginObject() + getIndexedOrExpando = fill( """ uint32_t index = GetArrayIndexFromId(id); @@ -12237,6 +12405,9 @@ class CGDOMJSProxyHandler_get(ClassMethod): getIndexedOrExpando = getUnforgeableOrExpando if self.descriptor.supportsNamedProperties(): + # We can't handle this for cross-origin objects + assert not self.descriptor.isMaybeCrossOriginObject() + getNamed = CGProxyNamedGetter(self.descriptor, templateValues) if self.descriptor.supportsIndexedProperties(): getNamed = CGIfWrapper(getNamed, "!IsArrayIndex(index)") @@ -12245,16 +12416,43 @@ class CGDOMJSProxyHandler_get(ClassMethod): getNamed = "" getOnPrototype = dedent(""" - bool foundOnPrototype; - if (!GetPropertyOnPrototype(cx, proxy, receiver, id, &foundOnPrototype, vp)) { + if (!GetPropertyOnPrototype(cx, proxy, rootedReceiver, id, &foundOnPrototype, vp)) { return false; } - if (foundOnPrototype) { - return true; - } - """) + + if self.descriptor.isMaybeCrossOriginObject(): + getOnPrototype = fill( + """ + bool foundOnPrototype; + { // Scope for JSAutoRealm + JSAutoRealm ar(cx, proxy); + // We already wrapped rootedReceiver + MOZ_ASSERT_IF(rootedReceiver.isObject(), + js::IsObjectInContextCompartment(&rootedReceiver.toObject(), cx)); + JS_MarkCrossZoneId(cx, id); + $*{getOnPrototype} + } + + if (foundOnPrototype) { + return MaybeWrapValue(cx, vp); + } + + """, + getOnPrototype=getOnPrototype) + else: + getOnPrototype = fill( + """ + bool foundOnPrototype; + $*{getOnPrototype} + if (foundOnPrototype) { + return true; + } + + """, + getOnPrototype=getOnPrototype) + if self.descriptor.interface.getExtendedAttribute('OverrideBuiltins'): getNamed = getNamed + getOnPrototype else: @@ -12265,12 +12463,16 @@ class CGDOMJSProxyHandler_get(ClassMethod): MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy), "Should not have a XrayWrapper here"); + $*{maybeCrossOriginGet} + JS::Rooted rootedReceiver(cx, receiver); + $*{indexedOrExpando} $*{named} vp.setUndefined(); return true; """, + maybeCrossOriginGet=maybeCrossOriginGet, indexedOrExpando=getIndexedOrExpando, named=getNamed) @@ -12342,7 +12544,23 @@ class CGDOMJSProxyHandler_className(ClassMethod): self.descriptor = descriptor def getBody(self): - return 'return "%s";\n' % self.descriptor.name + if self.descriptor.isMaybeCrossOriginObject(): + crossOrigin = dedent( + """ + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return "Object"; + } + + """) + else: + crossOrigin = "" + return fill( + """ + $*{crossOrigin} + return "${name}"; + """, + crossOrigin=crossOrigin, + name=self.descriptor.name) class CGDOMJSProxyHandler_finalizeInBackground(ClassMethod): @@ -12457,23 +12675,6 @@ class CGDOMJSProxyHandler_getInstance(ClassMethod): """) -class CGDOMJSProxyHandler_getPrototypeIfOrdinary(ClassMethod): - def __init__(self): - args = [Argument('JSContext*', 'cx'), - Argument('JS::Handle', 'proxy'), - Argument('bool*', 'isOrdinary'), - Argument('JS::MutableHandle', 'proto')] - - ClassMethod.__init__(self, "getPrototypeIfOrdinary", "bool", args, - virtual=True, override=True, const=True) - - def getBody(self): - return dedent(""" - *isOrdinary = false; - return true; - """) - - class CGDOMJSProxyHandler_call(ClassMethod): def __init__(self): args = [Argument('JSContext*', 'cx'), @@ -12518,6 +12719,171 @@ class CGDOMJSProxyHandler_canNurseryAllocate(ClassMethod): """) +class CGDOMJSProxyHandler_getOwnPropertyDescriptor(ClassMethod): + """ + Implementation of getOwnPropertyDescriptor. We only use this for + cross-origin objects. + """ + def __init__(self, descriptor): + assert descriptor.isMaybeCrossOriginObject() + + args = [Argument('JSContext*', 'cx'), + Argument('JS::Handle', 'proxy'), + Argument('JS::Handle', 'id'), + Argument('JS::MutableHandle', 'desc')] + ClassMethod.__init__(self, "getOwnPropertyDescriptor", "bool", args, + virtual=True, override=True, const=True) + self.descriptor = descriptor + + def getBody(self): + return dedent( + """ + // Implementation of . + MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy)); + + // Step 1. + if (IsPlatformObjectSameOrigin(cx, proxy)) { + { // Scope so we can wrap our PropertyDescriptor back into + // the caller compartment. + // Enter the Realm of "proxy" so we can work with it. + JSAutoRealm ar(cx, proxy); + + JS_MarkCrossZoneId(cx, id); + + // The spec messes around with configurability of the returned + // descriptor here, but it's not clear what should actually happen + // here. See . For + // now, keep our old behavior and don't do any magic. + if (!dom::DOMProxyHandler::getOwnPropertyDescriptor(cx, proxy, id, desc)) { + return false; + } + } + return JS_WrapPropertyDescriptor(cx, desc); + } + + // Step 2. + if (!CrossOriginGetOwnPropertyHelper(cx, proxy, id, desc)) { + return false; + } + + // Step 3. + if (desc.object()) { + return true; + } + + // And step 4. + return CrossOriginPropertyFallback(cx, proxy, id, desc); + """) + + +class CGDOMJSProxyHandler_getSameOriginPrototype(ClassMethod): + """ + Implementation of getSameOriginPrototype. We only use this for + cross-origin objects. + """ + def __init__(self, descriptor): + assert descriptor.isMaybeCrossOriginObject() + + args = [Argument('JSContext*', 'cx')] + ClassMethod.__init__(self, "getSameOriginPrototype", "JSObject*", args, + virtual=True, override=True, const=True) + self.descriptor = descriptor + + def getBody(self): + return dedent( + """ + return GetProtoObjectHandle(cx); + """) + + +class CGDOMJSProxyHandler_definePropertySameOrigin(ClassMethod): + """ + Implementation of definePropertySameOrigin. We only use this for + cross-origin objects. + """ + def __init__(self, descriptor): + assert descriptor.isMaybeCrossOriginObject() + + args = [Argument('JSContext*', 'cx'), + Argument('JS::Handle', 'proxy'), + Argument('JS::Handle', 'id'), + Argument('JS::Handle', 'desc'), + Argument('JS::ObjectOpResult&', 'result')] + ClassMethod.__init__(self, "definePropertySameOrigin", "bool", args, + virtual=True, override=True, const=True) + self.descriptor = descriptor + + def getBody(self): + return dedent( + """ + return dom::DOMProxyHandler::defineProperty(cx, proxy, id, desc, result); + """) + + +class CGDOMJSProxyHandler_set(ClassMethod): + """ + Implementation of set(). We only use this for cross-origin objects. + """ + def __init__(self, descriptor): + assert descriptor.isMaybeCrossOriginObject() + + args = [Argument('JSContext*', 'cx'), + Argument('JS::Handle', 'proxy'), + Argument('JS::Handle', 'id'), + Argument('JS::Handle', 'v'), + Argument('JS::Handle', 'receiver'), + Argument('JS::ObjectOpResult&', 'result')] + ClassMethod.__init__(self, "set", "bool", args, + virtual=True, override=True, const=True) + self.descriptor = descriptor + + def getBody(self): + return dedent( + """ + if (!IsPlatformObjectSameOrigin(cx, proxy)) { + return CrossOriginSet(cx, proxy, id, v, receiver, result); + } + + // Safe to enter the Realm of proxy now, since it's same-origin with us. + JSAutoRealm ar(cx, proxy); + JS::Rooted wrappedReceiver(cx, receiver); + if (!MaybeWrapValue(cx, &wrappedReceiver)) { + return false; + } + + JS::Rooted wrappedValue(cx, v); + if (!MaybeWrapValue(cx, &wrappedValue)) { + return false; + } + + JS_MarkCrossZoneId(cx, id); + + return dom::DOMProxyHandler::set(cx, proxy, id, wrappedValue, wrappedReceiver, result); + """) + + +class CGDOMJSProxyHandler_EnsureHolder(ClassMethod): + """ + Implementation of set(). We only use this for cross-origin objects. + """ + def __init__(self, descriptor): + args = [Argument('JSContext*', 'cx'), + Argument('JS::Handle', 'proxy'), + Argument('JS::MutableHandle', 'holder')] + ClassMethod.__init__(self, "EnsureHolder", "bool", args, + virtual=True, override=True, const=True) + self.descriptor = descriptor + + def getBody(self): + return dedent( + """ + // Our holder slot is our last slot. + return EnsureHolder(cx, proxy, + JSCLASS_RESERVED_SLOTS(js::GetObjectClass(proxy)) - 1, + sCrossOriginAttributes, sCrossOriginMethods, holder); + """) + + class CGDOMJSProxyHandler(CGClass): def __init__(self, descriptor): assert (descriptor.supportsIndexedProperties() or @@ -12549,8 +12915,6 @@ class CGDOMJSProxyHandler(CGClass): (descriptor.operations['NamedSetter'] is not None and descriptor.interface.getExtendedAttribute('OverrideBuiltins'))): methods.append(CGDOMJSProxyHandler_setCustom(descriptor)) - if descriptor.isMaybeCrossOriginObject(): - methods.append(CGDOMJSProxyHandler_getPrototypeIfOrdinary()) if descriptor.operations['LegacyCaller']: methods.append(CGDOMJSProxyHandler_call()) methods.append(CGDOMJSProxyHandler_isCallable()) @@ -12562,8 +12926,22 @@ class CGDOMJSProxyHandler(CGClass): if descriptor.wrapperCache: methods.append(CGDOMJSProxyHandler_objectMoved(descriptor)) + if descriptor.isMaybeCrossOriginObject(): + methods.extend([ + CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor), + CGDOMJSProxyHandler_getSameOriginPrototype(descriptor), + CGDOMJSProxyHandler_definePropertySameOrigin(descriptor), + CGDOMJSProxyHandler_set(descriptor), + CGDOMJSProxyHandler_EnsureHolder(descriptor), + ClassUsingDeclaration("MaybeCrossOriginObjectMixins", + "EnsureHolder") + ]) + if descriptor.interface.getExtendedAttribute('OverrideBuiltins'): + assert not descriptor.isMaybeCrossOriginObject() parentClass = 'ShadowingDOMProxyHandler' + elif descriptor.isMaybeCrossOriginObject(): + parentClass = 'MaybeCrossOriginObject' else: parentClass = 'mozilla::dom::DOMProxyHandler' @@ -12831,8 +13209,9 @@ class CGDescriptor(CGThing): # after we have our DOMProxyHandler defined. if descriptor.wantsXrays: if descriptor.concrete and descriptor.proxy: - cgThings.append(CGResolveOwnProperty(descriptor)) - cgThings.append(CGEnumerateOwnProperties(descriptor)) + if not descriptor.isMaybeCrossOriginObject(): + cgThings.append(CGResolveOwnProperty(descriptor)) + cgThings.append(CGEnumerateOwnProperties(descriptor)) if descriptor.needsXrayNamedDeleterHook(): cgThings.append(CGDeleteNamedProperty(descriptor)) elif descriptor.needsXrayResolveHooks(): @@ -14206,6 +14585,10 @@ class CGBindingRoot(CGThing): descriptorRequiresPreferences(d) for d in descriptors) bindingHeaders["mozilla/dom/DOMJSProxyHandler.h"] = any( d.concrete and d.proxy for d in descriptors) + hasCrossOriginObjects = any( + d.concrete and d.isMaybeCrossOriginObject() for d in descriptors) + bindingHeaders["mozilla/dom/MaybeCrossOriginObject.h"] = hasCrossOriginObjects + bindingHeaders["AccessCheck.h"] = hasCrossOriginObjects hasCEReactions = any(d.hasCEReactions() for d in descriptors) bindingHeaders["mozilla/dom/CustomElementRegistry.h"] = hasCEReactions bindingHeaders["mozilla/dom/DocGroup.h"] = hasCEReactions diff --git a/dom/bindings/Configuration.py b/dom/bindings/Configuration.py index f1e46d1bb1f8..66f3a9c6f7d3 100644 --- a/dom/bindings/Configuration.py +++ b/dom/bindings/Configuration.py @@ -496,6 +496,16 @@ class Descriptor(DescriptorProvider): self.isMaybeCrossOriginObject()) if self.proxy: + if (self.isMaybeCrossOriginObject() and + (self.supportsIndexedProperties() or + self.supportsNamedProperties())): + raise TypeError("We don't support named or indexed " + "properties on maybe-cross-origin objects. " + "This lets us assume that their proxy " + "hooks are never called via Xrays. " + "Fix %s.\n%s" % + (self.interface, self.interface.location)) + if (not self.operations['IndexedGetter'] and (self.operations['IndexedSetter'] or self.operations['IndexedDeleter'])): From ffd07255aa6f31d60c316bfdc7f36463cacf7bfb Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:33:32 +0000 Subject: [PATCH 11/33] Bug 1363208 part 8. Stop using cross-origin Xrays for Location. r=peterv The test change is because it was testing Window, not Location. Differential Revision: https://phabricator.services.mozilla.com/D15432 --HG-- extra : moz-landing-system : lando --- js/xpconnect/wrappers/WrapperFactory.cpp | 8 +------- js/xpconnect/wrappers/WrapperFactory.h | 3 +-- .../cross-origin-objects.html | 16 +++++++++++----- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index caddde1195e6..fbb40268cc4e 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -396,13 +396,7 @@ static const Wrapper* SelectWrapper(bool securityWrapper, XrayType xrayType, // This is a security wrapper. Use the security versions and filter. if (xrayType == XrayForDOMObject && - IdentifyCrossOriginObject(obj) == CrossOriginLocation) { - return &FilteringWrapper::singleton; - } - - if (xrayType == XrayForDOMObject && - IdentifyCrossOriginObject(obj) == CrossOriginWindow) { + IdentifyCrossOriginObject(obj) != CrossOriginOpaque) { return &CrossOriginObjectWrapper::singleton; } diff --git a/js/xpconnect/wrappers/WrapperFactory.h b/js/xpconnect/wrappers/WrapperFactory.h index ad0ac49ea356..829f74d90d4c 100644 --- a/js/xpconnect/wrappers/WrapperFactory.h +++ b/js/xpconnect/wrappers/WrapperFactory.h @@ -60,8 +60,7 @@ class WrapperFactory { } static bool IsCrossOriginWrapper(JSObject* obj) { - return IsXrayWrapper(obj) || - (js::IsProxy(obj) && + return (js::IsProxy(obj) && js::GetProxyHandler(obj) == &CrossOriginObjectWrapper::singleton); } diff --git a/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html b/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html index 918293836188..888343b45bcd 100644 --- a/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html +++ b/testing/web-platform/tests/html/browsers/origin/cross-origin-objects/cross-origin-objects.html @@ -106,16 +106,22 @@ addTest(function() { C.location[prop]; // Shouldn't throw. Object.getOwnPropertyDescriptor(C.location, prop); // Shouldn't throw. assert_true(Object.prototype.hasOwnProperty.call(C.location, prop), "hasOwnProperty for " + prop); + assert_throws("SecurityError", function() { C.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location"); + } + else if (prop == 'href') { + Object.getOwnPropertyDescriptor(C.location, prop); // Shouldn't throw. + assert_true(Object.prototype.hasOwnProperty.call(C.location, prop), "hasOwnProperty for " + prop); + assert_throws("SecurityError", function() { C.location[prop] }, + "Should throw reading href on Location"); } else { - assert_throws("SecurityError", function() { C[prop]; }, "Should throw when accessing " + prop + " on Location"); - assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(C, prop); }, + assert_throws("SecurityError", function() { C.location[prop]; }, "Should throw when accessing " + prop + " on Location"); + assert_throws("SecurityError", function() { Object.getOwnPropertyDescriptor(C.location, prop); }, "Should throw when accessing property descriptor for " + prop + " on Location"); - assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(C, prop); }, + assert_throws("SecurityError", function() { Object.prototype.hasOwnProperty.call(C.location, prop); }, "Should throw when invoking hasOwnProperty for " + prop + " on Location"); + assert_throws("SecurityError", function() { C.location[prop] = undefined; }, "Should throw when writing to " + prop + " on Location"); } - if (prop != 'href') - assert_throws("SecurityError", function() { C[prop] = undefined; }, "Should throw when writing to " + prop + " on Location"); } }, "Only whitelisted properties are accessible cross-origin"); From e5c8ead70a5548f6dceade9a22ab054443b1d48b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 21 Jan 2019 03:33:55 +0000 Subject: [PATCH 12/33] Bug 1363208 part 9. Remove now-unused cross-origin Xray infrastructure. r=peterv Differential Revision: https://phabricator.services.mozilla.com/D15433 --HG-- extra : moz-landing-system : lando --- dom/bindings/Codegen.py | 60 ++--------- js/xpconnect/wrappers/AccessCheck.cpp | 115 --------------------- js/xpconnect/wrappers/AccessCheck.h | 28 ----- js/xpconnect/wrappers/FilteringWrapper.cpp | 102 ------------------ js/xpconnect/wrappers/FilteringWrapper.h | 32 ------ js/xpconnect/wrappers/XrayWrapper.cpp | 4 +- js/xpconnect/wrappers/XrayWrapper.h | 3 - 7 files changed, 8 insertions(+), 336 deletions(-) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 9b2d074fc85c..2d17aa78d7f5 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -4230,48 +4230,6 @@ class CGCrossOriginProperties(CGThing): methodSpecs=",\n".join(self.methodSpecs)) -class CGIsPermittedMethod(CGAbstractMethod): - """ - crossOriginGetters/Setters/Methods are sets of names of the relevant members. - """ - def __init__(self, descriptor, crossOriginGetters, crossOriginSetters, - crossOriginMethods): - self.crossOriginGetters = crossOriginGetters - self.crossOriginSetters = crossOriginSetters - self.crossOriginMethods = crossOriginMethods - args = [Argument("JSFlatString*", "prop"), - Argument("char16_t", "propFirstChar"), - Argument("bool", "set")] - CGAbstractMethod.__init__(self, descriptor, "IsPermitted", "bool", args, - inline=True) - - def definition_body(self): - allNames = self.crossOriginGetters | self.crossOriginSetters | self.crossOriginMethods - readwrite = self.crossOriginGetters & self.crossOriginSetters - readonly = (self.crossOriginGetters - self.crossOriginSetters) | self.crossOriginMethods - writeonly = self.crossOriginSetters - self.crossOriginGetters - cases = {} - for name in sorted(allNames): - cond = 'JS_FlatStringEqualsAscii(prop, "%s")' % name - if name in readonly: - cond = "!set && %s" % cond - elif name in writeonly: - cond = "set && %s" % cond - else: - assert name in readwrite - firstLetter = name[0] - case = cases.get(firstLetter, CGList([])) - case.append(CGGeneric("if (%s) {\n" - " return true;\n" - "}\n" % cond)) - cases[firstLetter] = case - caseList = [] - for firstLetter in sorted(cases.keys()): - caseList.append(CGCase("'%s'" % firstLetter, cases[firstLetter])) - switch = CGSwitch("propFirstChar", caseList) - return switch.define() + "\nreturn false;\n" - - class CGCycleCollectionTraverseForOwningUnionMethod(CGAbstractMethod): """ ImplCycleCollectionUnlink for owning union type. @@ -13037,7 +12995,7 @@ class CGDescriptor(CGThing): toBindingNamespace(descriptor.parentPrototypeName))) defaultToJSONMethod = None - crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set() + needCrossOriginPropertyArrays = False unscopableNames = list() for n in descriptor.interface.namedConstructors: cgThings.append(CGClassConstructor(descriptor, n, @@ -13067,7 +13025,7 @@ class CGDescriptor(CGThing): cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod)) cgThings.append(CGMemberJITInfo(descriptor, m)) if props.isCrossOriginMethod: - crossOriginMethods.add(m.identifier.name) + needCrossOriginPropertyArrays = True # If we've hit the maplike/setlike member itself, go ahead and # generate its convenience functions. elif m.isMaplikeOrSetlike(): @@ -13091,7 +13049,7 @@ class CGDescriptor(CGThing): if m.type.isPromise(): cgThings.append(CGGetterPromiseWrapper(descriptor, specializedGetter)) if props.isCrossOriginGetter: - crossOriginGetters.add(m.identifier.name) + needCrossOriginPropertyArrays = True if not m.readonly: if m.isStatic(): assert descriptor.interface.hasInterfaceObject() @@ -13099,11 +13057,11 @@ class CGDescriptor(CGThing): elif descriptor.interface.hasInterfacePrototypeObject(): cgThings.append(CGSpecializedSetter(descriptor, m)) if props.isCrossOriginSetter: - crossOriginSetters.add(m.identifier.name) + needCrossOriginPropertyArrays = True elif m.getExtendedAttribute("PutForwards"): cgThings.append(CGSpecializedForwardingSetter(descriptor, m)) if props.isCrossOriginSetter: - crossOriginSetters.add(m.identifier.name) + needCrossOriginPropertyArrays = True elif m.getExtendedAttribute("Replaceable"): cgThings.append(CGSpecializedReplaceableSetter(descriptor, m)) elif m.getExtendedAttribute("LenientSetter"): @@ -13255,13 +13213,9 @@ class CGDescriptor(CGThing): cgThings.append(CGGetConstructorObjectHandleMethod(descriptor)) cgThings.append(CGGetConstructorObjectMethod(descriptor)) - # See whether we need we need to generate an IsPermitted method - if crossOriginGetters or crossOriginSetters or crossOriginMethods: + # See whether we need to generate cross-origin property arrays. + if needCrossOriginPropertyArrays: cgThings.append(CGCrossOriginProperties(descriptor)) - cgThings.append(CGIsPermittedMethod(descriptor, - crossOriginGetters, - crossOriginSetters, - crossOriginMethods)) cgThings = CGList((CGIndenter(t, declareOnly=True) for t in cgThings), "\n") cgThings = CGWrapper(cgThings, pre='\n', post='\n') diff --git a/js/xpconnect/wrappers/AccessCheck.cpp b/js/xpconnect/wrappers/AccessCheck.cpp index f6f34c5bcf4e..d4828152a66d 100644 --- a/js/xpconnect/wrappers/AccessCheck.cpp +++ b/js/xpconnect/wrappers/AccessCheck.cpp @@ -89,53 +89,6 @@ bool AccessCheck::isChrome(JSObject* obj) { return isChrome(js::GetObjectCompartment(obj)); } -// Hardcoded policy for cross origin property access. See the HTML5 Spec. -static bool IsPermitted(CrossOriginObjectType type, JSFlatString* prop, - bool set) { - size_t propLength = JS_GetStringLength(JS_FORGET_STRING_FLATNESS(prop)); - if (!propLength) { - return false; - } - - char16_t propChar0 = JS_GetFlatStringCharAt(prop, 0); - if (type == CrossOriginLocation) { - return dom::Location_Binding::IsPermitted(prop, propChar0, set); - } - if (type == CrossOriginWindow) { - return dom::Window_Binding::IsPermitted(prop, propChar0, set); - } - - return false; -} - -static bool IsFrameId(JSContext* cx, JSObject* obj, jsid idArg) { - MOZ_ASSERT(!js::IsWrapper(obj)); - RootedId id(cx, idArg); - - nsGlobalWindowInner* win = WindowOrNull(obj); - if (!win) { - return false; - } - - nsDOMWindowList* col = win->GetFrames(); - if (!col) { - return false; - } - - nsCOMPtr domwin; - if (JSID_IS_INT(id)) { - domwin = col->IndexedGetter(JSID_TO_INT(id)); - } else if (JSID_IS_STRING(id)) { - nsAutoJSString idAsString; - if (!idAsString.init(cx, JSID_TO_STRING(id))) { - return false; - } - domwin = col->NamedItem(idAsString); - } - - return domwin != nullptr; -} - CrossOriginObjectType IdentifyCrossOriginObject(JSObject* obj) { obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false); const js::Class* clasp = js::GetObjectClass(obj); @@ -150,74 +103,6 @@ CrossOriginObjectType IdentifyCrossOriginObject(JSObject* obj) { return CrossOriginOpaque; } -bool AccessCheck::isCrossOriginAccessPermitted(JSContext* cx, - HandleObject wrapper, - HandleId id, - Wrapper::Action act) { - if (act == Wrapper::CALL) { - return false; - } - - if (act == Wrapper::ENUMERATE) { - return true; - } - - // For the case of getting a property descriptor, we allow if either GET or - // SET is allowed, and rely on FilteringWrapper to filter out any disallowed - // accessors. - if (act == Wrapper::GET_PROPERTY_DESCRIPTOR) { - return isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::GET) || - isCrossOriginAccessPermitted(cx, wrapper, id, Wrapper::SET); - } - - RootedObject obj( - cx, js::UncheckedUnwrap(wrapper, /* stopAtWindowProxy = */ false)); - CrossOriginObjectType type = IdentifyCrossOriginObject(obj); - if (JSID_IS_STRING(id)) { - if (IsPermitted(type, JSID_TO_FLAT_STRING(id), act == Wrapper::SET)) { - return true; - } - } - - if (type != CrossOriginOpaque && IsCrossOriginWhitelistedProp(cx, id)) { - // We always allow access to "then", @@toStringTag, @@hasInstance, and - // @@isConcatSpreadable. But then we nerf them to be a value descriptor - // with value undefined in CrossOriginXrayWrapper. - return true; - } - - if (act != Wrapper::GET) { - return false; - } - - // Check for frame IDs. If we're resolving named frames, make sure to only - // resolve ones that don't shadow native properties. See bug 860494. - if (type == CrossOriginWindow) { - if (JSID_IS_STRING(id)) { - bool wouldShadow = false; - if (!XrayUtils::HasNativeProperty(cx, wrapper, id, &wouldShadow) || - wouldShadow) { - // If the named subframe matches the name of a DOM constructor, - // the global resolve triggered by the HasNativeProperty call - // above will try to perform a CheckedUnwrap on |wrapper|, and - // throw a security error if it fails. That exception isn't - // really useful for our callers, so we silence it and just - // deny access to the property (since it matched a builtin). - // - // Note that this would be a problem if the resolve code ever - // tried to CheckedUnwrap the wrapper _before_ concluding that - // the name corresponds to a builtin global property, since it - // would mean that we'd never permit cross-origin named subframe - // access (something we regrettably need to support). - JS_ClearPendingException(cx); - return false; - } - } - return IsFrameId(cx, obj, id); - } - return false; -} - bool AccessCheck::checkPassToPrivilegedCode(JSContext* cx, HandleObject wrapper, HandleValue v) { // Primitives are fine. diff --git a/js/xpconnect/wrappers/AccessCheck.h b/js/xpconnect/wrappers/AccessCheck.h index 159dfd032f0d..597e0d50f0ae 100644 --- a/js/xpconnect/wrappers/AccessCheck.h +++ b/js/xpconnect/wrappers/AccessCheck.h @@ -24,9 +24,6 @@ class AccessCheck { JS::Compartment* b); static bool isChrome(JS::Compartment* compartment); static bool isChrome(JSObject* obj); - static bool isCrossOriginAccessPermitted(JSContext* cx, JS::HandleObject obj, - JS::HandleId id, - js::Wrapper::Action act); static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper, JS::HandleValue value); static bool checkPassToPrivilegedCode(JSContext* cx, JS::HandleObject wrapper, @@ -89,31 +86,6 @@ struct OpaqueWithCall : public Policy { } }; -// This policy only permits access to properties that are safe to be used -// across origins. -struct CrossOriginAccessiblePropertiesOnly : public Policy { - static bool check(JSContext* cx, JS::HandleObject wrapper, JS::HandleId id, - js::Wrapper::Action act) { - return AccessCheck::isCrossOriginAccessPermitted(cx, wrapper, id, act); - } - static bool deny(JSContext* cx, js::Wrapper::Action act, JS::HandleId id, - bool mayThrow) { - // Silently fail for enumerate-like operations. - if (act == js::Wrapper::ENUMERATE) { - return true; - } - if (mayThrow) { - AccessCheck::reportCrossOriginDenial(cx, id, - NS_LITERAL_CSTRING("access")); - } - return false; - } - static bool allowNativeCall(JSContext* cx, JS::IsAcceptableThis test, - JS::NativeImpl impl) { - return false; - } -}; - // This class used to support permitting access to properties if they // appeared in an access list on the object, but now it acts like an // Opaque wrapper, with the exception that it fails silently for GET, diff --git a/js/xpconnect/wrappers/FilteringWrapper.cpp b/js/xpconnect/wrappers/FilteringWrapper.cpp index 517336ed0732..2e261b620f59 100644 --- a/js/xpconnect/wrappers/FilteringWrapper.cpp +++ b/js/xpconnect/wrappers/FilteringWrapper.cpp @@ -237,116 +237,14 @@ bool FilteringWrapper::enter(JSContext* cx, HandleObject wrapper, return true; } -bool CrossOriginXrayWrapper::getPropertyDescriptor( - JSContext* cx, JS::Handle wrapper, JS::Handle id, - JS::MutableHandle desc) const { - if (!SecurityXrayDOM::getPropertyDescriptor(cx, wrapper, id, desc)) { - return false; - } - if (desc.object()) { - // Cross-origin DOM objects do not have symbol-named properties apart - // from the ones we add ourselves here. - MOZ_ASSERT(!JSID_IS_SYMBOL(id), - "What's this symbol-named property that appeared on a " - "Window or Location instance?"); - - // All properties on cross-origin DOM objects are |own|. - desc.object().set(wrapper); - - // All properties on cross-origin DOM objects are "configurable". Any - // value attributes are read-only. Indexed properties are enumerable, - // but nothing else is. - if (!JSID_IS_INT(id)) { - desc.attributesRef() &= ~JSPROP_ENUMERATE; - } - desc.attributesRef() &= ~JSPROP_PERMANENT; - if (!desc.getter() && !desc.setter()) { - desc.attributesRef() |= JSPROP_READONLY; - } - } else if (IsCrossOriginWhitelistedProp(cx, id)) { - // Spec says to return PropertyDescriptor { - // [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, - // [[Configurable]]: true - // }. - // - desc.setDataDescriptor(JS::UndefinedHandleValue, JSPROP_READONLY); - desc.object().set(wrapper); - } - - return true; -} - -bool CrossOriginXrayWrapper::getOwnPropertyDescriptor( - JSContext* cx, JS::Handle wrapper, JS::Handle id, - JS::MutableHandle desc) const { - // All properties on cross-origin DOM objects are |own|. - return getPropertyDescriptor(cx, wrapper, id, desc); -} - -bool CrossOriginXrayWrapper::ownPropertyKeys(JSContext* cx, - JS::Handle wrapper, - JS::AutoIdVector& props) const { - // All properties on cross-origin objects are supposed |own|, despite what - // the underlying native object may report. Override the inherited trap to - // avoid passing JSITER_OWNONLY as a flag. - if (!SecurityXrayDOM::getPropertyKeys(cx, wrapper, JSITER_HIDDEN, props)) { - return false; - } - - return AppendCrossOriginWhitelistedPropNames(cx, props); -} - -bool CrossOriginXrayWrapper::defineProperty(JSContext* cx, - JS::Handle wrapper, - JS::Handle id, - JS::Handle desc, - JS::ObjectOpResult& result) const { - AccessCheck::reportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("define")); - return false; -} - -bool CrossOriginXrayWrapper::delete_(JSContext* cx, - JS::Handle wrapper, - JS::Handle id, - JS::ObjectOpResult& result) const { - AccessCheck::reportCrossOriginDenial(cx, id, NS_LITERAL_CSTRING("delete")); - return false; -} - -bool CrossOriginXrayWrapper::setPrototype(JSContext* cx, - JS::HandleObject wrapper, - JS::HandleObject proto, - JS::ObjectOpResult& result) const { - // https://html.spec.whatwg.org/multipage/browsers.html#windowproxy-setprototypeof - // and - // https://html.spec.whatwg.org/multipage/browsers.html#location-setprototypeof - // both say to call SetImmutablePrototype, which does nothing and just - // returns whether the passed-in value equals the current prototype. Our - // current prototype is always null, so this just comes down to returning - // whether null was passed in. - // - // In terms of ObjectOpResult that means calling one of the fail*() things - // on it if non-null was passed, and it's got one that does just what we - // want. - if (!proto) { - return result.succeed(); - } - return result.failCantSetProto(); -} - -#define XOW \ - FilteringWrapper #define NNXOW FilteringWrapper #define NNXOWC FilteringWrapper -template <> -const XOW XOW::singleton(0); template <> const NNXOW NNXOW::singleton(0); template <> const NNXOWC NNXOWC::singleton(0); -template class XOW; template class NNXOW; template class NNXOWC; template class ChromeObjectWrapperBase; diff --git a/js/xpconnect/wrappers/FilteringWrapper.h b/js/xpconnect/wrappers/FilteringWrapper.h index 9c45571570d3..bfa3ee31d763 100644 --- a/js/xpconnect/wrappers/FilteringWrapper.h +++ b/js/xpconnect/wrappers/FilteringWrapper.h @@ -53,38 +53,6 @@ class FilteringWrapper : public Base { static const FilteringWrapper singleton; }; -/* - * The HTML5 spec mandates very particular object behavior for cross-origin DOM - * objects (Window and Location), some of which runs contrary to the way that - * other XrayWrappers behave. We use this class to implement those semantics. - */ -class CrossOriginXrayWrapper : public SecurityXrayDOM { - public: - constexpr explicit CrossOriginXrayWrapper(unsigned flags) - : SecurityXrayDOM(flags) {} - - virtual bool getOwnPropertyDescriptor( - JSContext* cx, JS::Handle wrapper, JS::Handle id, - JS::MutableHandle desc) const override; - virtual bool defineProperty(JSContext* cx, JS::Handle wrapper, - JS::Handle id, - JS::Handle desc, - JS::ObjectOpResult& result) const override; - virtual bool ownPropertyKeys(JSContext* cx, JS::Handle wrapper, - JS::AutoIdVector& props) const override; - virtual bool delete_(JSContext* cx, JS::Handle wrapper, - JS::Handle id, - JS::ObjectOpResult& result) const override; - - virtual bool getPropertyDescriptor( - JSContext* cx, JS::Handle wrapper, JS::Handle id, - JS::MutableHandle desc) const override; - - virtual bool setPrototype(JSContext* cx, JS::HandleObject wrapper, - JS::HandleObject proto, - JS::ObjectOpResult& result) const override; -}; - } // namespace xpc #endif /* __FilteringWrapper_h__ */ diff --git a/js/xpconnect/wrappers/XrayWrapper.cpp b/js/xpconnect/wrappers/XrayWrapper.cpp index d7edefd3fcde..627a42f3c354 100644 --- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -1874,8 +1874,7 @@ template bool XrayWrapper::getPropertyDescriptor( JSContext* cx, HandleObject wrapper, HandleId id, JS::MutableHandle desc) const { - // CrossOriginXrayWrapper::getOwnPropertyDescriptor calls this. - + // FIXME: This method is unused. Will get sorted out in bug 1160757. assertEnteredPolicy(cx, wrapper, id, BaseProxyHandler::GET | BaseProxyHandler::SET | BaseProxyHandler::GET_PROPERTY_DESCRIPTOR); @@ -2376,7 +2375,6 @@ const xpc::XrayWrapper xpc::XrayWrapper::singleton( 0); template class PermissiveXrayDOM; -template class SecurityXrayDOM; template class PermissiveXrayJS; template class PermissiveXrayOpaque; diff --git a/js/xpconnect/wrappers/XrayWrapper.h b/js/xpconnect/wrappers/XrayWrapper.h index 1b770df312df..b4a430b4bab2 100644 --- a/js/xpconnect/wrappers/XrayWrapper.h +++ b/js/xpconnect/wrappers/XrayWrapper.h @@ -446,15 +446,12 @@ class XrayWrapper : public Base { #define PermissiveXrayDOM \ xpc::XrayWrapper -#define SecurityXrayDOM \ - xpc::XrayWrapper #define PermissiveXrayJS \ xpc::XrayWrapper #define PermissiveXrayOpaque \ xpc::XrayWrapper extern template class PermissiveXrayDOM; -extern template class SecurityXrayDOM; extern template class PermissiveXrayJS; extern template class PermissiveXrayOpaque; From 4fa1e2f7b82e18536e5ebe60594e7b0b4e9c1962 Mon Sep 17 00:00:00 2001 From: James Teh Date: Mon, 21 Jan 2019 07:21:01 +0000 Subject: [PATCH 13/33] Bug 1521438: Correct IAccessible::get_accSelection implementation for no selection and single selection. r=MarcoZ Previously, we were always returning VT_UNKNOWN and an IEnumVARIANT. According to the IAccessible documentation, this should only be done for multiple selection. Change this to correctly return VT_EMPTY for no selection and VT_DISPATCH (with an accessible) for single selection. Differential Revision: https://phabricator.services.mozilla.com/D17091 --HG-- extra : moz-landing-system : lando --- accessible/windows/msaa/AccessibleWrap.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/accessible/windows/msaa/AccessibleWrap.cpp b/accessible/windows/msaa/AccessibleWrap.cpp index 86e52f0e5bd9..eee8031a5dc9 100644 --- a/accessible/windows/msaa/AccessibleWrap.cpp +++ b/accessible/windows/msaa/AccessibleWrap.cpp @@ -740,17 +740,25 @@ AccessibleWrap::get_accSelection(VARIANT __RPC_FAR* pvarChildren) { if (IsDefunct()) return CO_E_OBJNOTCONNECTED; - if (IsSelect()) { - AutoTArray selectedItems; - SelectedItems(&selectedItems); + if (!IsSelect()) { + return S_OK; + } - // 1) Create and initialize the enumeration + AutoTArray selectedItems; + SelectedItems(&selectedItems); + uint32_t count = selectedItems.Length(); + if (count == 1) { + pvarChildren->vt = VT_DISPATCH; + pvarChildren->pdispVal = NativeAccessible(selectedItems[0]); + } else if (count > 1) { RefPtr pEnum = new AccessibleEnumerator(selectedItems); pvarChildren->vt = VT_UNKNOWN; // this must be VT_UNKNOWN for an IEnumVARIANT NS_ADDREF(pvarChildren->punkVal = pEnum); } + // If count == 0, vt is already VT_EMPTY, so there's nothing else to do. + return S_OK; } From 06c4ca921f8d4c2c31faf1906c14c0d266b164c4 Mon Sep 17 00:00:00 2001 From: Florens Verschelde Date: Mon, 21 Jan 2019 07:24:49 +0000 Subject: [PATCH 14/33] Bug 1521105 - Align message-location and network request status text; r=nchevobbe Differential Revision: https://phabricator.services.mozilla.com/D16985 --HG-- extra : moz-landing-system : lando --- devtools/client/themes/webconsole.css | 32 ++++++++++++--------------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/devtools/client/themes/webconsole.css b/devtools/client/themes/webconsole.css index c2e96c4a49f9..935b81b9d9ae 100644 --- a/devtools/client/themes/webconsole.css +++ b/devtools/client/themes/webconsole.css @@ -70,6 +70,12 @@ a { position: relative; } +@media (min-width: 1000px) { + .message { + padding-inline-end: 12px; + } +} + /* * By default, prevent any element in message to overflow. * This makes console reflows faster (See Bug 1487457). @@ -260,39 +266,29 @@ a { max-width: 40vw; flex-shrink: 0; color: var(--frame-link-source); - margin-inline-start: 5px; - margin-inline-end: 10px; + margin-inline-start: 1ch; } -.stack-trace { - /* The markup contains extra whitespace to improve formatting of clipboard text. - Make sure this whitespace doesn't affect the HTML rendering */ - white-space: normal; +.message-location:empty { + display: none; } -.message-location, -.stack-trace .frame-link-source { +.message-location .frame-link-source { /* Makes the file name truncated (and ellipsis shown) on the left side */ direction: rtl; + display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: end; } -.stack-trace .frame-link-source-inner, .message-location .frame-link-source-inner { /* Enforce LTR direction for the file name - fixes bug 1290056 */ direction: ltr; unicode-bidi: embed; } -.stack-trace .frame-link-function-display-name { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - .message-flex-body { display: flex; } @@ -342,7 +338,7 @@ a { .message.network .status { flex: none; - margin-inline-start: 6px; + margin-inline-start: 1ch; cursor: default; } @@ -353,7 +349,7 @@ a { .message .learn-more-link { color: var(--theme-highlight-blue); - margin: 0 6px; + margin: 0 1ch; } .message.network .xhr { @@ -697,7 +693,7 @@ a.learn-more-link.webconsole-learn-more-link { /* Network Messages */ .webconsole-output-wrapper .message.network .method { - margin-inline-end: 5px; + margin-inline-end: 1ch; } .webconsole-output-wrapper .message.network .xhr { From 9f3d1f92c676da78e7661d79d2cf820835007d96 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Fri, 18 Jan 2019 04:50:02 +0000 Subject: [PATCH 15/33] Bug 886716 - Fix sorting of text-overflow:ellipsis relative to positioned content. r=mats Differential Revision: https://phabricator.services.mozilla.com/D15504 --HG-- extra : moz-landing-system : lando --- layout/generic/nsBlockFrame.cpp | 14 +++++------ .../reference/text-overflow-030-ref.html | 13 ++++++++++ .../tests/css/css-ui/text-overflow-030.html | 25 +++++++++++++++++++ 3 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 testing/web-platform/tests/css/css-ui/reference/text-overflow-030-ref.html create mode 100644 testing/web-platform/tests/css/css-ui/text-overflow-030.html diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index ac4e31b89d29..1ea77c9dd374 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -6515,15 +6515,15 @@ void nsBlockFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, } } - // Pick up the resulting text-overflow markers. We append them to - // PositionedDescendants just before we append the lines' display items, - // so that our text-overflow markers will appear on top of this block's - // normal content but below any of its its' positioned children. - if (textOverflow.isSome()) { - aLists.PositionedDescendants()->AppendToTop(&textOverflow->GetMarkers()); - } linesDisplayListCollection.MoveTo(aLists); + if (textOverflow.isSome()) { + // Put any text-overflow:ellipsis markers on top of the non-positioned + // content of the block's lines. (If we ever start sorting the Content() + // list this will end up in the wrong place.) + aLists.Content()->AppendToTop(&textOverflow->GetMarkers()); + } + if (HasOutsideBullet()) { // Display outside bullets manually nsIFrame* bullet = GetOutsideBullet(); diff --git a/testing/web-platform/tests/css/css-ui/reference/text-overflow-030-ref.html b/testing/web-platform/tests/css/css-ui/reference/text-overflow-030-ref.html new file mode 100644 index 000000000000..5e4f4936a1fa --- /dev/null +++ b/testing/web-platform/tests/css/css-ui/reference/text-overflow-030-ref.html @@ -0,0 +1,13 @@ + + +CSS Reference + +

Test passes if there is a green rectangle and no red.

+
diff --git a/testing/web-platform/tests/css/css-ui/text-overflow-030.html b/testing/web-platform/tests/css/css-ui/text-overflow-030.html new file mode 100644 index 000000000000..0ccd59c12a20 --- /dev/null +++ b/testing/web-platform/tests/css/css-ui/text-overflow-030.html @@ -0,0 +1,25 @@ + + +CSS Basic User Interface Test: ellipsis should render under other positioned content + + + + +

Test passes if there is a green rectangle and no red.

+
+
From e6aa11c2642937a6b70d37a82935478df4a22dee Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Mon, 21 Jan 2019 08:39:34 +0000 Subject: [PATCH 16/33] Bug 1517025 - Do not allow percent symbol in URL hostnames r=kershaw Differential Revision: https://phabricator.services.mozilla.com/D16694 --HG-- extra : moz-landing-system : lando --- netwerk/base/nsStandardURL.cpp | 6 +----- netwerk/test/unit/test_bug412457.js | 26 +++++++++++++------------- netwerk/test/unit/test_bug464591.js | 13 ++++++++++--- netwerk/test/unit/test_standardurl.js | 21 ++++++++++++++++++--- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp index 572737936bf5..b9f254c5d6a7 100644 --- a/netwerk/base/nsStandardURL.cpp +++ b/netwerk/base/nsStandardURL.cpp @@ -60,10 +60,6 @@ const char nsStandardURL::gHostLimitDigits[] = {'/', '\\', '?', '#', 0}; bool nsStandardURL::gPunycodeHost = true; // Invalid host characters -// We still allow % because it is in the ID of addons. -// Any percent encoded ASCII characters that are not allowed in the -// hostname are not percent decoded, and will be parsed just fine. -// // Note that the array below will be initialized at compile time, // so we do not need to "optimize" TestForInvalidHostCharacters. // @@ -73,7 +69,7 @@ constexpr bool TestForInvalidHostCharacters(char c) { return (c > 0 && c < 32) || // The control characters are [1, 31] c == ' ' || c == '#' || c == '/' || c == ':' || c == '?' || c == '@' || c == '[' || c == '\\' || c == ']' || c == '*' || c == '<' || - c == '>' || c == '|' || c == '"'; + c == '>' || c == '|' || c == '"' || c == '%'; } constexpr ASCIIMaskArray sInvalidHostChars = CreateASCIIMask(TestForInvalidHostCharacters); diff --git a/netwerk/test/unit/test_bug412457.js b/netwerk/test/unit/test_bug412457.js index 785b1c45fb48..13b5784cc3fa 100644 --- a/netwerk/test/unit/test_bug412457.js +++ b/netwerk/test/unit/test_bug412457.js @@ -29,17 +29,17 @@ function run_test() { newURI = newURI.mutate().setSpec("http://example.com/foo").finalize(); Assert.equal(newURI.asciiHost, "example.com"); - // Characters that are invalid in the host, shouldn't be decoded. - newURI = newURI.mutate().setSpec("http://example.com%3ffoo").finalize(); - Assert.equal(newURI.asciiHost, "example.com%3ffoo"); - newURI = newURI.mutate().setSpec("http://example.com%23foo").finalize(); - Assert.equal(newURI.asciiHost, "example.com%23foo"); - newURI = newURI.mutate().setSpec("http://example.com%3bfoo").finalize(); - Assert.equal(newURI.asciiHost, "example.com%3bfoo"); - newURI = newURI.mutate().setSpec("http://example.com%3a80").finalize(); - Assert.equal(newURI.asciiHost, "example.com%3a80"); - newURI = newURI.mutate().setSpec("http://example.com%2ffoo").finalize(); - Assert.equal(newURI.asciiHost, "example.com%2ffoo"); - newURI = newURI.mutate().setSpec("http://example.com%00").finalize(); - Assert.equal(newURI.asciiHost, "example.com%00"); + // Characters that are invalid in the host + Assert.throws(() => { newURI = newURI.mutate().setSpec("http://example.com%3ffoo").finalize(); }, + /NS_ERROR_MALFORMED_URI/, "bad escaped character"); + Assert.throws(() => { newURI = newURI.mutate().setSpec("http://example.com%23foo").finalize(); }, + /NS_ERROR_MALFORMED_URI/, "bad escaped character"); + Assert.throws(() => { newURI = newURI.mutate().setSpec("http://example.com%3bfoo").finalize(); }, + /NS_ERROR_MALFORMED_URI/, "bad escaped character"); + Assert.throws(() => { newURI = newURI.mutate().setSpec("http://example.com%3a80").finalize(); }, + /NS_ERROR_MALFORMED_URI/, "bad escaped character"); + Assert.throws(() => { newURI = newURI.mutate().setSpec("http://example.com%2ffoo").finalize(); }, + /NS_ERROR_MALFORMED_URI/, "bad escaped character"); + Assert.throws(() => { newURI = newURI.mutate().setSpec("http://example.com%00").finalize(); }, + /NS_ERROR_MALFORMED_URI/, "bad escaped character"); } diff --git a/netwerk/test/unit/test_bug464591.js b/netwerk/test/unit/test_bug464591.js index 398be921243f..87d47b02465c 100644 --- a/netwerk/test/unit/test_bug464591.js +++ b/netwerk/test/unit/test_bug464591.js @@ -5,11 +5,13 @@ let reference = [ ["www.example.com%e2%88%95www.mozill%d0%b0.com%e2%81%84www.mozilla.org", "www.example.xn--comwww-re3c.xn--mozill-8nf.xn--comwww-rq0c.mozilla.org"], - ["www.mozill%61%2f.org", "www.mozilla%2f.org"], // a slash is not valid in the hostname - ["www.e%00xample.com%e2%88%95www.mozill%d0%b0.com%e2%81%84www.mozill%61.org", - "www.e%00xample.xn--comwww-re3c.xn--mozill-8nf.xn--comwww-rq0c.mozilla.org"], ]; +let badURIs = [ + ["www.mozill%61%2f.org"], // a slash is not valid in the hostname + ["www.e%00xample.com%e2%88%95www.mozill%d0%b0.com%e2%81%84www.mozill%61.org"], +] + let prefData = [ { @@ -75,4 +77,9 @@ function run_test() { ok(false, "Error testing "+reference[i][0]); } } + + for (let i = 0; i < badURIs.length; ++i) { + Assert.throws(() => { let result = stringToURL("http://" + badURIs[i][0]).host; }, + /NS_ERROR_MALFORMED_URI/, "bad escaped character"); + } } diff --git a/netwerk/test/unit/test_standardurl.js b/netwerk/test/unit/test_standardurl.js index 6aa1b2f6f0d1..c22a90d9d87b 100644 --- a/netwerk/test/unit/test_standardurl.js +++ b/netwerk/test/unit/test_standardurl.js @@ -1,5 +1,6 @@ "use strict"; +ChromeUtils.import('resource://gre/modules/Services.jsm'); const gPrefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); function symmetricEquality(expect, a, b) @@ -312,9 +313,9 @@ add_test(function test_percentDecoding() var url = stringToURL("http://%70%61%73%74%65%62%69%6E.com"); Assert.equal(url.spec, "http://pastebin.com/"); - // We shouldn't unescape characters that are not allowed in the hostname. - url = stringToURL("http://example.com%0a%23.google.com/"); - Assert.equal(url.spec, "http://example.com%0a%23.google.com/"); + // Disallowed hostname characters are rejected even when percent encoded + Assert.throws(() => { url = stringToURL("http://example.com%0a%23.google.com/"); }, + /NS_ERROR_MALFORMED_URI/, "invalid characters are not allowed"); run_next_test(); }); @@ -696,3 +697,17 @@ add_test(function test_idna_host() { run_next_test(); }); + +add_test(function test_bug1517025() { + Assert.throws(() => { let other = stringToURL("https://b%9a/"); }, + /NS_ERROR_UNEXPECTED/, "bad URI"); + + Assert.throws(() => { let other = stringToURL("https://b%9ª/"); }, + /NS_ERROR_MALFORMED_URI/, "bad URI"); + + let base = stringToURL("https://bug1517025.bmoattachments.org/attachment.cgi?id=9033787"); + Assert.throws(() => { let uri = Services.io.newURI("/\\b%9ª", "windows-1252", base); }, + /NS_ERROR_MALFORMED_URI/, "bad URI"); + + run_next_test(); +}); From eaeb0a8a1c4bd46d9adad87f4d7b7c56a25e9961 Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Mon, 21 Jan 2019 09:55:02 +0000 Subject: [PATCH 17/33] Bug 1517025 - Change default pref URLs to localhost instead of %(server) r=Gijs We now disallow the % sign in the hostname of a URL. If the app.normandy.api_url pref isn't set explicitly, it'll remain the default set in xpcshell/user.js: https://%(server)s/selfsupport-dummy/. As you can see, this one has a % sign in it; and the test will fail. Otherwise, the error we catch is not a NormandyApi.InvalidSignatureError, but NS_ERROR_MALFORMED_URI. Differential Revision: https://phabricator.services.mozilla.com/D16695 --HG-- extra : moz-landing-system : lando --- testing/profiles/xpcshell/user.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/testing/profiles/xpcshell/user.js b/testing/profiles/xpcshell/user.js index 5f86f5bc085d..9a7763b80e85 100644 --- a/testing/profiles/xpcshell/user.js +++ b/testing/profiles/xpcshell/user.js @@ -1,16 +1,16 @@ // Base preferences file used by the xpcshell harness /* globals user_pref */ /* eslint quotes: 0 */ -user_pref("app.normandy.api_url", "https://%(server)s/selfsupport-dummy/"); -user_pref("browser.safebrowsing.downloads.remote.url", "https://%(server)s/safebrowsing-dummy"); -user_pref("browser.search.geoip.url", "https://%(server)s/geoip-dummy"); -user_pref("extensions.systemAddon.update.url", "http://%(server)s/dummy-system-addons.xml"); +user_pref("app.normandy.api_url", "https://localhost/selfsupport-dummy/"); +user_pref("browser.safebrowsing.downloads.remote.url", "https://localhost/safebrowsing-dummy"); +user_pref("browser.search.geoip.url", "https://localhost/geoip-dummy"); +user_pref("extensions.systemAddon.update.url", "http://localhost/dummy-system-addons.xml"); // Always use network provider for geolocation tests // so we bypass the OSX dialog raised by the corelocation provider user_pref("geo.provider.testing", true); user_pref("media.gmp-manager.updateEnabled", false); -user_pref("media.gmp-manager.url.override", "http://%(server)s/dummy-gmp-manager.xml"); -user_pref("toolkit.telemetry.server", "https://%(server)s/telemetry-dummy"); +user_pref("media.gmp-manager.url.override", "http://localhost/dummy-gmp-manager.xml"); +user_pref("toolkit.telemetry.server", "https://localhost/telemetry-dummy"); // The process priority manager only shifts priorities when it has at least // one active tab. xpcshell tabs don't have any active tabs, which would mean // all processes would run at low priority, which is not desirable, so we From 5f1bc348cdb7188e5925cefbce2ea4a7b1c69742 Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Mon, 21 Jan 2019 08:40:09 +0000 Subject: [PATCH 18/33] Bug 1517025 - Remove EXPECTED-FAIL for URL percent encoding tests r=kershaw Differential Revision: https://phabricator.services.mozilla.com/D16696 --HG-- extra : moz-landing-system : lando --- .../meta/url/url-constructor.html.ini | 30 ------------------- 1 file changed, 30 deletions(-) diff --git a/testing/web-platform/meta/url/url-constructor.html.ini b/testing/web-platform/meta/url/url-constructor.html.ini index 9c9123a7f2ee..455dff5ff9ce 100644 --- a/testing/web-platform/meta/url/url-constructor.html.ini +++ b/testing/web-platform/meta/url/url-constructor.html.ini @@ -89,33 +89,9 @@ [Parsing: against ] expected: FAIL - [Parsing: against ] - expected: FAIL - - [Parsing: against ] - expected: FAIL - - [Parsing: against ] - expected: FAIL - - [Parsing: against ] - expected: FAIL - - [Parsing: against ] - expected: FAIL - - [Parsing: against ] - expected: FAIL - - [Parsing: against ] - expected: FAIL - [Parsing: against ] expected: FAIL - [Parsing: against ] - expected: FAIL - [Parsing: against ] expected: FAIL @@ -447,15 +423,9 @@ [Parsing: against ] expected: FAIL - [Parsing: against ] - expected: FAIL - [Parsing: against ] expected: FAIL - [Parsing: against ] - expected: FAIL - [Parsing: against ] expected: FAIL From 177f356f36b0cd9036b938d505d800df64d0b076 Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Mon, 21 Jan 2019 08:40:29 +0000 Subject: [PATCH 19/33] Bug 1517025 - Add crashtest with invalid URL r=kershaw Differential Revision: https://phabricator.services.mozilla.com/D16817 --HG-- extra : moz-landing-system : lando --- dom/base/crashtests/1517025.html | 5 +++++ dom/base/crashtests/crashtests.list | 1 + 2 files changed, 6 insertions(+) create mode 100644 dom/base/crashtests/1517025.html diff --git a/dom/base/crashtests/1517025.html b/dom/base/crashtests/1517025.html new file mode 100644 index 000000000000..795af0a3a9dd --- /dev/null +++ b/dom/base/crashtests/1517025.html @@ -0,0 +1,5 @@ + + +